-
Notifications
You must be signed in to change notification settings - Fork 1.6k
implement C++ assert (stdio, apple) #612
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall structure looks good (knowing that the API largely comes from existing Firebase C++).
@@ -24,22 +24,45 @@ add_library( | |||
log_stdio.cc | |||
) | |||
|
|||
# log_apple can only built and tested on apple plaforms | |||
# assert_stdio can be built and tested everywhere | |||
add_library( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just save complexity here I think it's safe to put the log_foo and assert_foo implementations in the same library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, solved w/ merged
|
||
// Assert condition is true otherwise display the specified expression, | ||
// message and abort. Compiled out of release builds. | ||
#if !defined(NDEBUG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above: let's make #ifdef NDEBUG
the first case to avoid a double-negative.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
// Translates a C format string to the equivalent NSString without making a | ||
// copy. | ||
NSString* CStringToNSString(const char* format) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a function we're going to use a lot when interoperating with platform native APIs on iOS.
Let's put this in a separate utility. As a separate utility we should make it clear that this is merely wrapping the C string rather than copying it. Maybe WrapNSStringNoCopy
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
#import <Foundation/Foundation.h> | ||
|
||
#include <string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This does not appear to use C++ strings at all.
Perhaps you meant <string.h>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASSERT_H_ | ||
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASSERT_H_ | ||
|
||
#include <cstdlib> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this required? If so we probably want <stdlib.h>
since we've been using the C headers directly elsewhere.
Also there should be a newline between the system headers and our own headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
// Assert condition is true, if it's false log an assert with the specified | ||
// expression as a string. Compiled out of release builds. | ||
#if !defined(NDEBUG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I realize this is in the upstream but it's better to avoid a double-negative for readability's sake. Let's reorder this to put the production branch first.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
vfprintf(stderr, format, args); | ||
va_end(args); | ||
fprintf(stderr, "\n"); | ||
throw std::exception(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's just abort rather than throwing. We're going to end up needing to compile under -fno-exceptions
.
Also we should throw the exception with the assertion text included.
Maybe we can include absl/base/config.h
and then do the following:
std::string message;
// compute assertion message using snprintf and vsnprintf (see notes below)
#if ABSL_HAVE_EXCEPTIONS
throw std::exception(message);
#else
fprintf(stderr, "%s\n", message.c_str());
abort();
#endif
Note that as of Visual Studio 2013 we can do the following to compute the required size of the buffer for the message:
size_t size = vsnprintf(nullptr, 0, format.c_str(), args);
And you can write directly into string's buffer as of C++11 (see stack overflow for discussion).
std::string message;
message.resize(size + 1); // include space for terminating null
vsnprintf(&message[0], message.size(), format.c_str(), args);
message.resize(size);
Depending on how frequently we end up using this, we might consider moving this latter part out to a separate std::string FormatString(const char* format, va_list args)
function.
Also consider if this is the right exception type. Perhaps logic_error might be better?
See https://github.com/abseil/abseil-cpp/blob/master/absl/base/internal/throw_delegate.cc for more ideas about handing this with exceptions disabled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored w/ the new StringPrintf() helpers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Please take another look.
|
||
// Translates a C format string to the equivalent NSString without making a | ||
// copy. | ||
NSString* CStringToNSString(const char* format) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
vfprintf(stderr, format, args); | ||
va_end(args); | ||
fprintf(stderr, "\n"); | ||
throw std::exception(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refactored w/ the new StringPrintf() helpers.
@@ -24,22 +24,45 @@ add_library( | |||
log_stdio.cc | |||
) | |||
|
|||
# log_apple can only built and tested on apple plaforms | |||
# assert_stdio can be built and tested everywhere | |||
add_library( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ack, solved w/ merged
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASSERT_H_ | ||
#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASSERT_H_ | ||
|
||
#include <cstdlib> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
// Assert condition is true, if it's false log an assert with the specified | ||
// expression as a string. Compiled out of release builds. | ||
#if !defined(NDEBUG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
// Assert condition is true otherwise display the specified expression, | ||
// message and abort. Compiled out of release builds. | ||
#if !defined(NDEBUG) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
#import <Foundation/Foundation.h> | ||
|
||
#include <string> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
#import <Foundation/Foundation.h> | ||
|
||
#include <stdarg.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't do anything with varargs or C++ strings. Probably we can just #import Foundation and that's all we need, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
* limitations under the License. | ||
*/ | ||
|
||
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_IOS_UTIL_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This macro should end with STRING_APPLE_H_
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
namespace util { | ||
|
||
NSString* WrapNSStringNoCopy(const char* c_str) { | ||
return [[NSString alloc] initWithBytesNoCopy:(void*)c_str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prefer modern C++ casts (const_cast, static_cast, and reinterpret_cast) to old-style C casts.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
namespace firestore { | ||
namespace util { | ||
|
||
NSString* WrapNSStringNoCopy(const char* c_str) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this is just wrapping this call to the NSString initializer, should we make this implementation inline
in the header?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
* limitations under the License. | ||
*/ | ||
|
||
#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_IOS_UTIL_H_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
|
||
#import <Foundation/Foundation.h> | ||
|
||
#include <stdarg.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
* implement C++ assert (stdio, apple) * Update tests for firebase_firestore_util renames * renaming `assert.h` to `firebase_assert.h` * refactoring to a common `WrapNSStringNoCopy()`
Discussion
go/firestorecpplogassert
Testing
unit test (for each platform)
API Changes
not applicable