Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is this legal in C?

I am writing a toy C compiler for a compiler/language course at my university.

I'm trying to flesh out the semantics for symbol resolution in C, and came up with this test case which I tried against regular compilers clang & gcc.

void foo() { }
int main() { foo(5); } // foo has extraneous arguments

Most compilers only seem to warn about extraneous arguments.

Question: What is the fundamental reasoning behind this?

For my symbol table generation/resolution phase, I was considering a function to be a symbol with a return type, and several parametrized arguments (based on the grammar) each with a respective type.

Thanks.

like image 786
snap Avatar asked Mar 15 '11 03:03

snap


People also ask

What is a legal statement in C?

Example. Char a=65; It is a legal statement because we can initialize a variable with a constant. Static int p=20, q=p*p. It is an illegal statement because static variable has to be initialized by a constant but here q is not initialized with a constant.

Why is the statement a/b/c d not legal in C?

Since C language does not support chaining assignment like a=b=c; each assignment operator (=) operates on two operands only.

Which is a illegal declaration?

1. Which of the following declaration is illegal? Explanation: char[] str is a declaration in Java, but not in C. 2.

Why are we still using C?

The C programming language doesn't seem to have an expiration date. It's closeness to the hardware, great portability and deterministic usage of resources makes it ideal for low level development for such things as operating system kernels and embedded software.


2 Answers

A function with no listed arguments in the prototype is deemed to have an indeterminate number, not zero.

If you really want zero arguments, it should be:

void foo (void);

The empty-list variant is a holdover from ancient C, even before ANSI got their hands on it, where you had things like:

add_one(val)
int val;
{
    return val + 1;
}

(with int being the default return type and parameter types specified outside the declarator).

If you're doing a toy compiler and you're not worried about compliance with every tiny little piece of C99, I'd just toss that option out and require a parameter list of some sort.

It'll make your life substantially easier, and I question the need for people to use that "feature" anyway.

like image 146
paxdiablo Avatar answered Sep 19 '22 05:09

paxdiablo


It's for backward compatibility with ancient C compilers. Back before the earth cooled, all C function declarations looked roughly like:

int foo();
long bar();

and so on. This told the compiler that the name referred to a function, but did not specify anything about the number or types of parameters. Probably the single biggest change in the original (1989) C standard was adding "function prototypes", which allowed the number and type(s) of parameters to be declared, so the compiler could check what you passed when you called a function. To maintain compatibility for existing code, they decided that an empty parameter list would retain its existing meaning, and if you wanted to declare a function that took no parameters, you'd have to add void in place of the parameter list: int f(void);.

Note that in C++ the same is not true -- C++ eliminates the old style function declarations, and requires that the number and type(s) of all parameters be specified1. If you declare the function without parameters, that means it doesn't take any parameters, and the compiler will complain if you try to pass any (unless you've also overloaded the function so there's another function with the same name that can take parameters).

1 Though you can still use an ellipsis for a function that takes a variable parameter list -- but when/if you do so, you can only pass POD types as parameters.

like image 22
Jerry Coffin Avatar answered Sep 22 '22 05:09

Jerry Coffin