Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error checking through Macro

I want to compile a time error checking as mentioned below . But I am not able to find out how to use it inside main()?

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(12);
}

Below is the mentioned error

1--error C2332: 'struct' : missing tag name
2--error C2143: syntax error : missing ')' before '{'
3--error C2027: use of undefined type 'main::<unnamed-tag>'
4--error C2143: syntax error : missing ';' before '{'
5--error C2059: syntax error : ')'

Can anyone please let me know what I am doing wrong?

like image 910
Viku Avatar asked Dec 30 '12 02:12

Viku


People also ask

How do I show errors in an Excel macro?

To do this, click on 'Tools' and then click on 'Options'. In the options dialog box, make sure that the 'Auto Syntax Check' option is enabled. If the 'Auto Syntax Check' option is disabled, VBA will still highlight the line with the syntax error in red, but it will not show the error dialog box.

Which errors can occur in macros?

Syntax errors occur when program statements do not conform to the rules of the macro language. Or, you may refer to a variable out of scope, causing a macro variable resolution error. Execution errors (also called semantic errors) are usually errors in program logic.


3 Answers

EDIT: the question was originally tagged as C++, but now as just C.

I'm not going to chase further fundamental changes of the question.

Original answer for the C++ tagged question:


This source code:

#define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
#define BUILD_BUG_ON_NULL(e) ((void *)sizeof(struct { int:-!!(e); }))
int main(){
BUILD_BUG_ON_NULL(0);
}

compiled with g++ 4.7.1., produced

foo.cpp: In function 'int main()':
foo.cpp:4:1: error: types may not be defined in 'sizeof' expressions
foo.cpp:4:21: warning: statement has no effect [-Wunused-value]

Which says directly what’s wrong.

So it is a good idea to compile with different compilers.


Possibly you’re looking for compile time assertions.

With C++11 you can use static_assert, e.g. via a macro such as

#define STATIC_ASSERT( e ) static_assert( e, #e )

In C++03 you could implement it as a valid/invalid typedef, because a typedef can be repeated in the same translation unit, and can be used in a class definition:

#define STATIC_ASSERT( e ) typedef char staticAssert_shouldBeTrue[e? 1 : -1]

One problem with that was that g++ had/has a compiler bug, where a repeated typedef is not always accepted as it should be, necessitating generation of a locally unique name for each one, e.g. by using __LINE__.

But you can always just use the definition in the Boost library, since Boost supports most extant compilers with special-casing for each one as necessary.

like image 111
Cheers and hth. - Alf Avatar answered Oct 19 '22 20:10

Cheers and hth. - Alf


First the macros BUILD_BUG_ON_ZERO and BUILD_BUG_ON_NULL trigger a compilation error if their argument is different than 0.

If the macro argument is 0, they will not trigger any compilation error but yield a 0 for BUILD_BUG_ON_ZERO and a (void *) 0 for BUILD_BUG_ON_NULL

These macros comes from the Linux kernel which is written in C and they are only working for C programs.

In C++ these macros are not working. The reason is in C++ you cannot declare a structure in a sizeof expression.

You don't mention in your question if you are compiling your program in C or in C++, but I strongly suspect you are compiling it in C++. So don't use these macros in C++.

like image 5
ouah Avatar answered Oct 19 '22 18:10

ouah


Compiling with gcc -std=c99 -pedantic-errors, I get

screwed.c: In function ‘main’:
screwed.c:5:1: error: negative width in bit-field ‘<anonymous>’
screwed.c:5:1: error: struct has no named members [-pedantic]

and those are the errors the compilation should give when the code is compiled as C. The width of a bit-field must be non-negative (positive if it has a name), and a struct must have at least one named member (two, if the last one is a flexible array member). structs without tags are allowed.

You either compiled the code not as C, or your compiler is non-conforming.

When compiling as C++, the additional error

error: types may not be defined in ‘sizeof’ expressions

is generated (but the one about the struct without named members disappears).

In C++, you may not define type in a sizeof expression, and your compiler chose a less clear way of telling you.

like image 2
Daniel Fischer Avatar answered Oct 19 '22 19:10

Daniel Fischer