7

According to this answer using function main() is illegal (§3.6.1.3) and a function is used if its name appears in a potentially evaluated expression (§3.2).

Suppose I have this code:

printf( "%p", &main );

in which name of function main() appears in expression &main.

Will the code above be illegal?

Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • 4
    §3.2 defines "*odr-used*", not "used". I think the meaning of "used" here is much more general - you cannot make use of `main` in any way whatsoever. – Joseph Mansfield Mar 20 '13 at 14:04
  • 1
    Nice question. Out of curiosity - why would you need this? Or asking your question is based on the same, I'm asking mine :) – Kiril Kirov Mar 20 '13 at 14:11
  • @sftrabbit C++03 says clearly: "An object or non-overloaded function is used if its name appears in a potentially-evaluated expression." C++11 doesn't say what it means by "used"; my guess is that "odr-used" was introduced to solve some other problem, and nobody got around to fixing the restriction on `main`. – James Kanze Mar 20 '13 at 14:11
  • @JamesKanze Ah, I was looking at C++11. – Joseph Mansfield Mar 20 '13 at 14:12
  • also see [this question](http://stackoverflow.com/questions/2741683/how-to-format-a-function-pointer) regarding printing a function pointer. – msam Mar 20 '13 at 14:12
  • @sftrabbit The words restricting the use of `main` are the same in both versions. I can't find any real definition as to what "used" means in C++11, however; unless someone can show me something else, I'll assume that the intent is the same as in C++03. – James Kanze Mar 20 '13 at 14:15
  • @KirilKirov: I don't know why I'd need this. I think that would be a good separate question. – sharptooth Mar 20 '13 at 14:16
  • It seems like an awfully dumb rule. This will effectively ban C++ from all manner of boot loaders and initialization code that needs to run before main() is called. At the same time, the C++ standard dictates that such code must exist, to handle static initialization and to run constructors of file scope objects. I suppose you are forced to write that code in C or assembler. – Lundin Mar 20 '13 at 14:30

3 Answers3

3

Yes. As you quote, the standard says that you cannot use main.

Note too that the address of a function does not match "%p". The corresponding argument must have type void*; any other type (except maybe char*) is illegal, and results in undefined behavior.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • So will I need a cast for the function address to pass it in place of `%p`? – sharptooth Mar 20 '13 at 14:04
  • 1
    @sharptooth Except that there is no conversion from pointer to function to `void*`. (I think C++11 makes this an optional feature, but in earlier versions, it required a diagnostic.) – James Kanze Mar 20 '13 at 14:05
0

Since main is not "used" (you're not evaluating it) then it should be legal according the link you supplied.

Tomer Arazy
  • 1,833
  • 10
  • 15
-3

It's not usual to use pointer to main() or the address of main() but..

Anyway, it is allowed since, as every function (and any symbol, e.g. variable) it has its own address. And the address of main() may be needed - especially when you write code for embedded systems and you play with dynamic loading of the code or run-time inspection. Or there are a bootloader and actual running firmware.

Often main() is an entry point to the dynamically loaded code (e.g from FLASH to RAM) and thus it is referenced (called directly or assigned to the relevant pointer) in bootloader.

Refer to MicroC-OS/II or VxWorks - both use main() in this way

Robert Mutke
  • 2,757
  • 1
  • 16
  • 14
  • 1
    Unfortunately... that is completely outside the Standard. The implementation is allowed all the black magic, platform-specific code, compiler-specific code it can muster; but that does not say anything about the *portability* of the program to another platform/compiler. – Matthieu M. Mar 20 '13 at 14:46
  • I suppose that the life saver in embedded systems is that main() can be replaced with something completely custom. So, since the C++ standard is retarded, all embedded C++ implementations need to rename their main to something else. I propose that all embedded systems use `another_wg21_fiasco()` instead of `main()`, to solve this issue. Or... they could simply keep programming in C, where the standard is less retarded. – Lundin Mar 20 '13 at 16:33