mitchalsup@aol.com (MitchAlsup1) writes:
On Sun, 8 Sep 2024 2:47:38 +0000, Tim Rentsch wrote:
>
mitchalsup@aol.com (MitchAlsup1) writes:
>
On Sat, 7 Sep 2024 23:45:45 +0000, Tim Rentsch wrote:
>
Another issue is that main() may not have the 3 defined arguments
and the containing environment is not supposed to complain when
argc, arv, and envp are unused or even unnamed as arguments.
>
The usual "Hello, World" program defines main() either with no
arguments
>
int
main(){
...
}
>
or with two arguments
>
int
main( int argc, char *argv[] ){
...
}
>
and in both cases main() has defined behavior and does not
violate the strictures of strictly conforming programs.
>
The Linux environment (crt0) calls main with 3 arguments.
The C standard allows defining main() either with no parameters,
with two parameters (of types int and char **), or "in some other
implementation-defined manner". (Note: this rule applies only
to hosted implementations; freestanding implementations have a
different rule. Compilers on Linux are hosted implementations.)
On Ubuntu Linux, both gcc and clang accept (under -pedantic with
either -std=c99 or -std=c11) this input
#include <stdio.h>
int
main(){
printf( "Hello, world\n" );
return 0;
}
and this input
#include <stdio.h>
int
main( int argc, char *argv[] ){
printf( "Hello, world\n" );
return 0;
}
and this input
#include <stdio.h>
int
main( int argc, char *argv[], char *envp[] ){
printf( "Hello, world\n" );
return 0;
}
without giving any diagnostics. The executable produced in each
case runs fine. In fact using -S to look at generated code, all
three compile to the same code (different generated code under
gcc compared to clang, but the same code for all versions under
each compiler).
As a sanity check, I tried this input
#include <stdio.h>
int
main( int argc, char *argv[], double *envp[] ){
printf( "Hello, world\n" );
return 0;
}
which from gcc gives a warning diagnostic, and from clang gives
an error diagnostic. The generated code under gcc is the same as
that produced by gcc for the other inputs, and the produced
executable runs and does the same thing as the other versions (as
one would expect, since the generated code is the same).
Are you arguing that a program can be strictly conforming and
not be type safe at its call/return interfaces ??
Both of the first two versions (with a no-parameters main() and
with a two-parameter main()) satisfy all the criteria of strictly
conforming programs.
The third version (with a third parameter of type char **) does
not satisfy the definition of strictly conforming programs,
because it uses a feature not specified as part of the language
or library -- namely, the implementation-defined form of main().
The C standard requires every implementation to accept all
strictly conforming programs (or the implementation is not
conforming if it chooses not to accept a SC program for any
reason). We don't expect all C compilers to accept a main()
defined with three parameters, which is consistent with the
rule that they are required to accept all strictly conforming
programs.
Does this explanation help clear things up? Or is there still
some aspect I haven't explained adequately?