Reputation: 687
This snippet in cppreference doesn't compile. I understand the problem has to do with the fact that the assert
macro is expanded in the global scope. That is, if we include the part of code below, starting with assert(sieof(S)==8);
inside a function, like main()
for example, the code will work.
#include <cassert>
struct S {
char c; // 1 byte value
// 3 bytes padding
float f; // 4 bytes value
bool operator==(const S& arg) const { // value-based equality
return c == arg.c && f == arg.f;
}
};
assert(sizeof(S) == 8);
S s1 = {'a', 3.14};
S s2 = s1;
reinterpret_cast<char*>(&s1)[2] = 'b'; // change 2nd byte
assert(s1 == s2); // value did not change
But I want to understand why the code doesn't compile, as stated in the original code. For example in VS2013, the macro is defined as follows:
#define assert(_Expression) (void)( (!!(_Expression)) ||
(_wassert(_CRT_WIDE(#_Expression), _CRT_WIDE(__FILE__), __LINE__), 0) )
and the compiler complains with the following error message:
error C2062: type 'void' unexpected
The obvious question is: why is the void
accepted inside main
but not in the global scope?
See the error messages in clang.
Upvotes: 2
Views: 1444
Reputation: 70283
The assert()
macro is a run-time assertion. It resolves to code, not a variable declaration / definition, and as such is not permitted at global scope.
The code after the struct
definition is supposed to be inside some surrounding function; as-is it's more like pseudo-code to reinforce the point the surrounding text is making.
They just didn't bother with actually putting an int main()
in the example at the appropriate place. Notice that there is no "run this code" button either -- that snippet is not supposed to be compiled as-is.
Upvotes: 2
Reputation: 172
assert() must in function like:
#include <cassert>
struct S {
char c; // 1 byte value
// 3 bytes padding
float f; // 4 bytes value
bool operator==(const S& arg) const { // value-based equality
return c == arg.c && f == arg.f;
}
};
int main(){
assert(sizeof(S) == 8);
S s1 = {'a', 3.14};
S s2 = s1;
reinterpret_cast<char*>(&s1)[2] = 'b'; // change 2nd byte
assert(s1 == s2); // value did not change
return 0;
}
Upvotes: 1
Reputation: 241771
Global scope can only contain declarations. The assert macro expands to an expression statement, which cannot appear at global scope.
Upvotes: 3