4

Why does the following print 1. I was expecting it to print the address of the function pointer.

#include <stdio.h>

int main(main) {
  printf("%i",main);
  return 0;
}
shreyasva
  • 13,126
  • 25
  • 78
  • 101
  • 2
    `main` wouldn't be an `int`, so due to the `%i` you'd have undefined behaviour anyway - all bets are off, it may as well go eat your IDE's logfile and print the first number it finds it it. –  Jul 25 '11 at 19:15

6 Answers6

10

Pointers must be printed with %p. Anyway here there's an "aliasing" problem, rather odd but that's it: main gets the value of the first argument to function main that is, what usually is called "argc". if you call it with more arguments, you should see bigger number.

ShinTakezou
  • 9,432
  • 1
  • 29
  • 39
  • of course, being `main` as func "ghosted" by using the name for the first argument to the function, the `%i` is appropriate since `main` ends to be an integer. – ShinTakezou Jul 25 '11 at 19:18
  • **Data** pointers must be printed with %p (ref: "The argument shall be a pointer to void" (7.19.6.1)). Function pointers cannot be converted to void*, only to other function pointer types. – Pascal Cuoq Jul 26 '11 at 19:45
  • @Pascal I suppose this is a misinterpretation.Elsewhere someone can say that a pointer (no matter to what) is not guaranteed to fit the size of any integer type,so that there would be no way to print it, e.g. with %lu, %llu.Function pointers can be converted to void* (cite the std part prohibiting it, UB?; I tried it gcc -ansi -strict and was ok).The cited sentence says that %p gets a "generic" pointer, w/o any reference to what, as obvious;it does not say that it must point to "data" (code is data, btw). – ShinTakezou Jul 27 '11 at 05:29
  • C99 6.3.2.3 paragraph 8 lists the conversions you can do with function pointers. Converting to `void*` is not in the list. Function pointers do not have to be the same size as data pointers, and indeed, with some memory models of x86_64 (and with older architectures), they aren't. – Pascal Cuoq Jul 27 '11 at 06:21
  • << ... 2) has x86_64 regs wider than 64, or specialized regs for addresses for code and data?? If not, it means x86_64 does not distinguish between a "number" that was a pointer to data or to code; so that the wider register (say, the 64bit eax, I don't know its name, let's call it qax) can hold pointers of any kind; though when using them you must know the difference, but once into qax, there's no difference and they can be printed as if they were a "generic" pointer, so print with %llx could be appropriate, but %p would be better and still ok despite the pointer's origin. ... > – ShinTakezou Jul 27 '11 at 06:51
  • ... with the -pedantic option gcc warns about the fact that ISO C forbids the conversion **if I put it explicitly**; no warns whatever when I let it push the function pointer on the stack, and let %p read it unless I add -Wformat; so, at the end, which is the right way to print a pointer to a func?? it seems there's no way at all (always warn with -Wformat) – ShinTakezou Jul 27 '11 at 07:01
  • There is no portable way that I know of for printing a function pointer. Related StackOverflow question: http://stackoverflow.com/questions/2741683/how-to-format-a-function-pointer – Pascal Cuoq Jul 27 '11 at 08:00
  • that's odd; assembly is highly unportable, though through it, it is always possible; so, I would expect a language providing features about pointers should allow it, compensating for machine differences: portability should be the same as, say, int a = c + b; (and if it makes sense at all file I/O for that system, of course) – ShinTakezou Jul 27 '11 at 09:10
3

Because the first argument of a program's main function is the argument count (plus one, since the program's name is the first argument) at runtime. Assuming you invoked your program with no arguments, that value will be populated with an integer.

Many people traditionally use main with the following signature:

int main(int argc, char **argv);

If you remove the parameter, you might get what you want:

int main() {
    printf("%i", main);
    return 0;
}

If that doesn't work, try declaring int main(); above the function definition.

If THAT doesn't work, ask yourself why you're doing this in the first place. :-P

Platinum Azure
  • 45,269
  • 12
  • 110
  • 134
1

you declared a param with the name "main" - this param corresponds to the first param of the main function in C which in turn is usually called "argc" which in turn is 1 if you start you program whithout any commandline params.

Yahia
  • 69,653
  • 9
  • 115
  • 144
1

The first parameter to main is usually called argc which tells you how many arguments the program was run with. Since you are running this with no arguments the value will be 1 (The name of the executable) If you run this from command line with extra arguments separated by spaces that number will increase.

Paul
  • 139,544
  • 27
  • 275
  • 264
1

This is equivalent to

#include <stdio.h>

int main(int main) {
    printf("%i",main);
    return 0;
}

So main is the first parameter of the main function. If called without parameters the size of the (normally following) argv array is 1, argv[0] holding the name of the process.

phlogratos
  • 13,234
  • 1
  • 32
  • 37
1

You include main as a parameter to the function main. This gets the first value normally given to main, that is, the size of the arguments passed to the program. If you don't pass arguments to the program, still the arguments hold the name of the program being executed, so the size of the argument list is 1, what it is printed.

Diego Sevilla
  • 28,636
  • 4
  • 59
  • 87