Why having assert before main() causing syntax error “error: expected ')' before numeric constant”?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



Why having assert before main() causing syntax error “error: expected ')' before numeric constant”?



Why assert is causing compilation error if I use it before main() call? It causes compilation error (Syntax error):



test.cpp:4:8: error: expected ')' before numeric constant



Note: I'm trying to understand why I'm a getting a syntax error for calling it outside main. That too related to something like "numeric constant", but not like function / macro called out side main function. If the error was simpler like function / macro called out side main, then my question wouldn't have made any sense.


#include <stdio.h>
#include <assert.h>

assert(0); //If I comment assert from here, then it compiles fine.

int main()

assert(0);
return 0;





Because you can't call assert from outside of main / a function.
– Sombrero Chicken
Aug 12 at 17:56



assert


main





Or more accuratelly, you can't call anything when not in function.
– Adrijaned
Aug 12 at 17:59





Because assert is actually code (or nothing).
– Matt
Aug 12 at 17:59


assert





Outside a function you can only have definitions and declarations, not general statements. Any book or tutorial or class (even bad ones) should have told you that. There are a few other exceptions to that rule, but they are very language-specific.
– Some programmer dude
Aug 12 at 18:00






Currently this is unclear since the rules for C and C++ differ in this respect. Please remove one of the tags.
– Bathsheba
Aug 12 at 18:28




4 Answers
4



Since all the other answers are "it didn't work because you can't do that", here's one that dives in to why the error message looks the way it does.



The short reason is compilers aren't smart, and they don't make good teachers.



When we, the experienced human programmers, look at this code


assert(0);
int main(void)



we recognize the first line as an attempt to call a function, and use that as the starting point of an explanation about why it's invalid and what you should have written instead. There's a bit of mind-reading involved in the recognition of your intent, because you expressed that intent with incorrect code.



The compiler can't read your mind, and by definition the only way it can recognize your intent is if your code is valid. Since it doesn't understand what you're trying to do, it can't give helpful advice.



What the compiler is actually doing is just taking in your code, one token at a time, and parsing it according to a grammar. If the code is ungrammatical, there will be a point at which the next token doesn't match any grammar rules. The compiler then tells you what the offending token was. In this case the offending token was the numeric constant 0.


0



The tokens preceding the 0 were parsed without complaint, but that doesn't mean they were interpreted the way you intended them.


0



It's hard to completely analyze this specific case because <assert.h> declares assert as a macro, and I don't know what it expands to on your system. To make the explanation a little easier, let's use a normal function:


<assert.h>


assert


/* sample program 1 */
foo(0);
int main(void)



The above code fails to compile. My compiler says


error: expected declaration specifiers or '...' before numeric constant



But this slightly altered version:


/* sample program 2 */
foo();
int main(void)



compiles with only some warnings, because in old-style C, the first line is a valid declaration of a function foo, using the implicit int return type! If my intent was to somehow "call foo before main" then it's a total failure. If my intent was to only declare foo then I'm only guilty of using an obsolete language feature.


foo


int


foo


foo



Now, knowing about the second sample, look back at the first sample. When the compiler reads the first 2 tokens, foo and (, everything is fine. The program still fits the grammar of (old-fashioned) C. Then it gets to the 0 and there's no way to proceed. So it tells me that the numeric constant is the problem.


foo


(


0



Now what about those things it says it was "expecting"? Those are the tokens that can come next in a valid program. It suggests a declaration specifier list rather than an immediate ), because this is valid too:


)


foo(int);
int main()



Even this, using an old-style function definition, would be a possible continuation:


foo(i)
int i;


int main()



Bottom line: whenever there's a parse error, the compiler reports the point where your program diverged grammatically from the set of all possible valid programs. The point where the parse diverged semantically from your intent is sometimes earlier. Sometimes a lot earlier. In that case, the compiler's "expected" tokens can be quite irrelevant.



You can't call free functions (be it assert (which is usually a macro, but still ends up being code that is run in global scope like a function) or any other function) from the global scope (you can however call functions as part of initializing a global variable (in C++)). That's why.


assert



Move the assert into main or some other function.


assert


main





Anonymous downvoter: care to explain why you believe this doesn't answer the question?
– Jesper Juhl
Aug 12 at 18:04





A couple of possibilities: assert is a macro, and you can call functions from the global scope (for example const static int = do_something();
– juanchopanza
Aug 12 at 18:09


assert


const static int = do_something();





@juanchopanza fair point. I'll update the answer.
– Jesper Juhl
Aug 12 at 18:12





You can have static_assert(...) outside a function though!
– Anthony Sottile
Aug 12 at 18:15


static_assert(...)





@Anthony Sottile - static_assert is a declaration though, not a function.
– Jesper Juhl
Aug 12 at 18:17



static_assert



In the C language the code can be executed only inside the functions. So if you place any code outside the functions you will get the compile errors.



C++ allows global variables to be initialized by non constants as the constructors are called during the object creation.



main is the entry point of your program. The only code run before main is initialization code. If you want to have assert run before main, you can have a global class with assert in its constructor, like:


main


main


main


class assert_class
assert_class() assert(0);
;
assert_class assert_here;

int main()





Your answer, Answers the question "How to call assert() before main? " but it doesn't explains any thing about the syntax error: error: expected ')' before numeric constant, which compiler is giving me. I tried running the code in different compiler but the same error. This gives me a feeling that there might be some specific reason behind such a weird syntax. Rather being simple error "function called out of main"
– Mohammed Zaed
Aug 12 at 18:54


syntax error: error: expected ')' before numeric constant





You can't have assert by itself because there is no way to get to the code. The only code executed in your program is either init code (as I showed) or is called by main. The assert code may as well be in a different file on a disk in a different room, since there is no path to get to the code. The error is just saying that the parser expected assert( to be followed by ), not 0)
– stark
Aug 12 at 19:26



assert(


)


0)






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard