4 ms·
It's called a K&R style function definition, which was the way to do it back in the day. Basically, you define your parameter names first, then you define the p
by rmrfrmrf 13y ago
It's called a K&R style function definition, which was the way to do it back in the day. Basically, you define your parameter names first, then you define the parameter types immediately after the function but before the opening curly brace. It's definitely not recommended today and can result in undefined behavior if your compiler doesn't recognize it. If you're working with legacy code, though, I'm pretty sure you can set some C compilers to allow for it.
To explain further:
main(argc, argv)
int argv[]; {
is equivalent to:
int main(int argc, int argv[]) {
The old style definition works because C had a default type of int, so the type specifications for the function main and the parameter argc could be omitted.
As for int argv[]? What that actually represents is an array of memory addresses that hold the command line arguments given. Obviously this becomes a problem if you're on a 64-bit system, where int and (void * ) are two different sizes. However, I checked this out on my 64-bit machine and it works just fine:
int main(int argc, unsigned long long argv[]) {
char *firstarg = (void *)(argv[1]);
printf("%s", firstarg);
}
which, given "./a.out pickles" will print "pickles" (argv[0] gives the memory address of the cstring "./a.out"). I'm guessing that, in the case of a compiler, the memory addresses of arguments are more relevant to have than the arguments themselves.
- _kst_ 13y agoThe 1999 ISO C standard dropped the "implicit int" rule, so this: main(argc, argv) char *argv[]; { /* ... */ } is illegal (strictly speaking, it's a "constraint violation"). Note that it's char *argv[] not int argv[] But this: int main(argc, argv) int argc; char *argv[]; { /* ... */ } is still perfectly valid. As for this: int main(int argc, unsigned long long argv[]) { char *firstarg = (void *)(argv[1]); printf("%s", firstarg); } it's not a constraint violation, but its behavior is undefined (unless your compiler specifically supports and documents that particular form as an extension).
- rmrfrmrf 13y agoWe're talking about the code from the actual source files, not the standard. Look here (lines 22 and 23): https://github.com/mortdeus/legacy-cc/blob/master/prestruct/c00.c https://github.com/mortdeus/legacy-cc/blob/master/prestruct/... The compiler code states int argv[], not char argv[] (I assumed this is why the OP asked for clarification in the first place, since char argv[] is much more common). You're right, in theory this is undefined behavior, but in practice on a 32-bit system, sizeof(int) will almost always be equal to sizeof(void *). I was just demonstrating how one could recreate the code in the compiler while on a 64-bit architecture.