what is main(ac, av) int ac; char **av; {...}? [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How many styles of writing functions are there in C?
I saw a program written in C with the following definition of main:
main(ac, av) int ac; char **av;
{
...
}
instead of
int main(int argc, char **argc)
{
...
}
I've never seen a C syntax as in the first code. What is it and where can I read about it?

The first one is an old-style, pre-ANSI, C function header before function prototypes became the common/standard way of writing code.
Frequently formatted like this:
main(ac, av)
int ac;
char **av;
{
...
}
What you see after the initial set of parenthesis are the type declarations for the parameters in main. Also note, no int return type is declared.
No one really writes code like that, stick to the 2nd form.
If you can dig up the original white book by Kernighan and Ritchie (1st ed, pre-ANSI) you'll see that form (and as #dirkgently correctly mentions this is sometimes referred to as K&R style C) as you would in other older C books.
Also check out this link if you are curious
Obsolete Forms of Function Declarations and Definitions. Searching on "old style C function declarations" in google will bring up a number of hits.

Related

C: What is the effect/meaning of declaring a variable after it is used? [duplicate]

This question already has answers here:
Identifier list Vs Parameter type list in C
(3 answers)
Alternative (K&R) C syntax for function declaration versus prototypes
(5 answers)
Closed 3 years ago.
I am reading Ken Thompson's Reflections on Trusting Trust and have come across a piece of example code that I don't quite understand (Figures 3.*).
Figure 3.1:
compile(s)
char *s;
{
...
}
Figure 3.2:
compile(s)
char *s;
{
if (match(s, "pattern")) {
compile("bug");
return;
}
...
}
Figure 3.3:
compile(s)
char *s;
{
if (match(s, "pattern1")) {
compile("bug1");
return;
}
if (match(s, "pattern2")) {
compile("bug2");
return;
}
...
}
What is the meaning of char s[]; after compile(s)?
Also, why is there a block of code that doesn't belong to a function initialisation or if/else/while/do statement?
This is an old, obsolete syntax for declaring the type of the parameters of a function. You declare the types of the parameters after the line that contains the name of the function and its parameters, but before the opening brace that starts the body of the function.
compile(s)
char *s;
{
/* function body goes here */
}
The reason for this weird syntax is that it evolved from B, a predecessor of C, which did not have any type declarations: a variable was a machine word (a “cell”), and it was up to the programmer to use it correctly. See “The Problems of B” in “The Development of the C language” by Dennis Ritchie. With no types, to define a function, you'd just write
compile(s)
{
/* function body goes here */
}
In early C, parameter declarations were optional, so existing code kept working. If something's type wasn't declared, it defaulted to int.
This declaration syntax is part of the first version of the C language, called K&R C after the authors of the seminal book about C, Brian Kernighan and Dennis Ritchie. In the late 1980s and 1990s, there was a gradual move to a newer version of the language called ANSI C or C89 or C90 (1989 and 1990 are the years the ANSI and ISO standards specifying the new version of the language came out). One of the main changes of ANSI C was in how function parameters are declared. In post-1990 C, you declare the type of parameters directly inside the parentheses, and you also declare the return type of the function (this is mandatory since C99, although many compilers still assume int if the return type is omitted).
int compile(char *s)
{
/* function body goes here */
}
That is the K&R style of declaring the type of an argument.
The function named compile takes an argument named s, whose type is char [] and returns an int.
Most likely it is old code.
These days one would use something like this
int compile(char *s)
{
}

declaring a function with this specification [duplicate]

This question already has answers here:
Function declaration: K&R vs ANSI [duplicate]
(3 answers)
Closed 6 years ago.
i recently saw the following code in C which is said to be valid but I'm not sure.
int max(x,y)
int x,y;
{
return (x>y)?x:y;
}
Is this kind of function prototype valid? If so please give some reference to learn more about that.
This is the old-style "K&R" way of defining functions. The new way is better, so don't write code like this yourself.
This code is valid, it's just a pretty old standard.
Nowadays in function declaration the types of arguments are declared right before the names of these arguments:
int main(int argc, char **argv)
But years ago there was another standard where the syntax was different: you had to specify the types like this:
int main(argc, argv)
int argc; char **argv;
So, nothing weird here, different standards offer different syntax

Why the program compiles?

I am just trying to understand this C code ( not trying to achieve any functional goal by the program). This compiles using gcc.
Is this main in
main(int a, char *argv[] )
format? Is it permissible to declare anything beween argument and function body (similar to char *a; here)?
#include <stdio.h>
main(u,_,a)
char
*a;
{
//printf("%s\n",_,a);//just to help debugging
//printf("%d\n",u); //just to help debugging
}
This is an old, obsolete way of writing C functions.
In an ancestor language of C, there were no types: all variables contained a machine word. So a function definition would start like this:
main(u, _, a) {
/* ... some code ... */
}
C as it used to be, known as “K&R C” from the authors of the seminal book about C (Brian Kernighan and Dennis Ritchie) added types in a form that looked like variable declarations, and were between the list of function parameters and the code of the function.
int main(u, _, a)
int u;
int _;
char *a;
{
/* ... some code ... */
}
In K&R C, if a type is int, then in many places it can be omitted. For a function parameter, you can omit the type declaration line altogether.
int main(u, _, a)
char *a;
{
/* ... some code ... */
}
ANSI C was standardized in 1989, and one of its main innovations was function prototypes. In proper ANSI C, you declare all functions before use and you declare the types of all arguments.
int main(int u, int _, char *a)
{
/* ... some code ... */
}
C compilers still support the old form for legacy code. (If they conform to the 1989 C standard, they have to.) There isn't much legacy code left after more than 20 years, so you won't find such code often.
(Note that this is not the right type for main. I think Gcc will warn you about that but you may have to turn the warning settings up.)
Declarations between argument list and function body were part of the so called K&R C (the first version of C). So yes, they are valid, if your compiler can compile K&R code.
About main() having more than two arguments... yes, in fact, main can have up to three arguments:
int main (int argc, char *argv[], char *envp[]);
The third argument being an array of pointers to strings, containing each one of them a environment variable definition (a string in the form name=value)
That's an old declaration that nobody uses anymore except for obfuscation (see also: trigraphs!). I think it is illegal under the new C standards, but gcc still supports it for backward compatibility.
The way it works is the types are listed under the function, and the return type is left off. No return type means it defaults to int. The typical main function could be written this way:
main(argc, argv)
int argc;
char** argv;
{
printf("%d\n", argc);
return 0;
}
You cannot declare other variables before the opening brace. Try adding int c; and get this error:
test.c:4: error: declaration for parameter ‘c’ but no such parameter
This is an invalid form of main declaration. This is invalid in C99 / C11 but also invalid in C90.
(See 5.1.2.2.1 for valid declarations of main function in C90).

What's the use case of foo() meaning foo has an unknown amount of arguments? [duplicate]

This question already has answers here:
int foo (int argc, ...) vs int foo() vs int foo(void) in C
(4 answers)
Closed 9 years ago.
So I was recently reading a bit on Hacker News about function pointers and was enlightened to the fact that void foo() and void foo(void) are NOT equivalent prototypes. So, I set about ensuring that this is actually true:
int foo()
{
return 0;
}
int main()
{
return foo(1,2,3,4);
}
Sure enough, this code compiles without even so much as a warning.. where as this code will throw an error:
int foo(void)
{
return 0;
}
int main()
{
return foo(1,2,3,4);
}
This seems very error prone. I also thought that ... for "any amount of arguments", such as in printf's signature
int printf ( const char * format, ... );
Was this also true in C89 or K&R? Can anyone give insight into the use case for this "feature"?
It's not really a "feature", per se. It's just the way the language used to be back in the beginning, so the syntax has lived on to keep old code working. The addition of void made it possible to have functions that explicitly took no arguments, for example.
The use of the ... indicates a variadic function, which is subtly different from a function that just takes an arbitrary number of arguments, though. Using the ... requires the use of stdarg.h macros, but just having a function declared with () doesn't.

In C: Difference between main() and int main () [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
difference between main(void) and main() in c
I know this is super basic and some other threads already talked about similar questions. But I have a book (Absolute Beginners Guide to C) where all the code is written within the function main(). The int is always left out. How is that possible to run? Is that ok with maybe an older version of stdio.h?
Here is the sample code:
#include <stdio.h>
main() // not int main()
{
printf("This is it\n");
return 0;
}
I think the c89 standard will allow main() but c99 and above won't . You have to use int main() otherwise .
These kind of questions are highly standard-version dependent, so a general answer doesn't make much sense.
From a C89 draft (correct me if official C89 Standard is different, it's not freely avalaible):
The function called at program startup is named main.
The implementation declares no prototype for this function.
It can be defined with no parameters:
int main(void) { /*...*/ }
or with two parameters (referred to here as argc and argv, though any names may be used, as they are local to the function in which they are declared):
int main(int argc, char *argv[]) { /*...*/ }
C99 and C11 standard say the same but they add something at the and:
[...]
or equivalent;[9] or in some other implementation-defined manner.
[9] Thus, int can be replaced by a typedef name defined as int, or the type of argv can be written as char ** argv, and so on.
In general things that are not defined from the standard leads to undefined behavior, so that code is UB in C89/C90, and it could be valid in C99 and C11, but that's implementation-defined.
P. S.: as you can see, you should also add void in the parameters list, without it the behavior is defined as above.
main() works but is confusing, in C the main function always returns an int, to specify exit status, so the correct syntax is int main(), but if you do not bother to set the exit status then main() is enough, but the good C books will always have int main().

Resources