Catching variables passed to function with no arguments - c

I don't know if it's possible but the wikipedia article here Compatibility of C and C++ says the following :
In C, a function prototype without arguments, e.g. int foo();,
implies that the parameters are unspecified. Therefore, it is legal to
call such a function with one or more arguments, e.g. foo(42, "hello
world").
In contrast, in C++ a function prototype without arguments
means that the function takes no arguments, and calling such a
function with arguments is ill-formed.
In C, the correct way to
declare a function that takes no arguments is by using void, as in
int foo(void);.
I made the following code to test it and catch the passed variables (which doesn't work quite right)
#include<stdio.h>
#include<stdarg.h>
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo()
{
// va_list args;
// va_start(args);
//
// int x = va_arg (args, int);
// printf("%d", x);
// va_end(args);
}
Is it possible to catch the passed i or is Wikipedia talking about something completely different?

You can't, at least not in standard C. What the Wikipedia article means is this code:
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo(int i)
{
(void)i;
}
Compiles fine in C, but it's invalid in C++ because the number of arguments don't match.

If you read the documentation for va_start you will see that it needs the last "real" argument in the argument list. So it's not possible in plain C to get the arguments if you don't declare any arguments.
What you can do is to declare the function prototype without arguments, and have arguments in the actual definition.

That comes from the old C days when the strictness of the language was, well..., relaxed.
The basic idea was that if you had a function in a translation unit, say foo.c:
float foo(int x)
{
return 2.0F * x;
}
And then you want to use it in another translation unit, say main.c but you don't want to bother with writing a header file, you could just do:
int main()
{
float foo();
float r;
r = foo(42);
}
And you don't have to write the arguments of the function. To be fair, you didn't have to write the prototype at all, but then the compiler would assume that the function always returns int which may not be what you need.
Then, as the language matured, this kind of function declaration was decided to be a very bad idea, so generally speaking you should not (try to) use it. If you want a variadic function, then by all means use it, but declare it as such. And you have to give it at least a real argument, to anchor the call to va_start().

You can call the function with any arguments, but you can't access them in the function scope. Anyway some compilers will give you warnings if you don't declare the prototype as int foo (void); since you probably don't want to do this anyway.

There is a way to access those parameters in C program, but I look at it as a big hack, which should be avoided.
Next example shows how to access an int parameter :
#include<stdio.h>
#include<stdarg.h>
void foo();
int main()
{
int i = 3;
foo(i);
return 0;
}
void foo(int p)
{
printf("%d",p);
}
Now, I am not sure what happens if you pass something else then int (for example char*), but it may cause an undefined behavior.
In c++ (as said), you can not pass parameters to functions taking no parameters.

Related

Calling of C functions with undefined number of parameters

Note this question does not refer to ellipsis.
Consider the following code
#include <stdio.h>
void foo() {
printf("I AM AWESOME\n");
}
main(void) {
foo(1,2,3);
foo();
return 0;
}
This program runs perfectly and provides the output.
However, in case of 'main', this works irrespective of
main(void)
or
main()
When, defining foo as
foo(void)
gives an error - "too many arguments".
If both are functions, shouldn't they also follow the same rules?
When you declare a function without parameters it means to disable type checking and to use K&R calling convention. It does not mean that the function does not have parameters.
In ANSI when you want to explicitly say that the function does not have parameters, you need to declare it as fun(void).
the is also somethg else in C called variable number of arguments
void foo(int x, ...)
https://www.geeksforgeeks.org/variable-length-argument-c/
The foo(void) takes no arguments (!!!), whereas foo() takes an unspecified number of arguments!

What are the differences between: main(){}, int main(){} and int main(void){} [duplicate]

This question already has answers here:
What should main() return in C and C++?
(19 answers)
Why is the type of the main function in C and c++ left to the user to define? [duplicate]
(6 answers)
Closed 9 years ago.
I am currently learning C and I have written many small programs. However, I have noticed that the main function could start as
main()
{
//code
}
or
int main()
{
//code
return 0;
}
or
int main(void)
{
//code
return 0;
}
Which option should I use? Thanks!
For Standard C
For a hosted environment (that's the normal one), the C99 standard
says:
5.1.2.2.1 Program startup
The function called at program startup is named main. The implementation declares no prototype for this function. It shall be
defined with a return type of int and 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[]) { /* ... */ }
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.
This (is valid in C89) main() implicitly meant (previously) int main(void). However the default return type rule has been abandoned in C99. Also:
main() means - a function main taking an unspecified number of arguments of.
main(void) means "a function main taking no arguments.
Your first example uses a feature inherited from the outdated dialect of C which predated the first ANSI(1989) and ISO(1990) standard: namely, that you can write a function which doesn't specify its return type, and in that case the type defaults to int.
In early C, the void keyword and associated type did not exist. When programmers wanted to write procedures ("functions that have a side effect, but do not return anything"), they simulated it using this feature. They wrote a function without any keyword specifying the return type. They allowed the function to execute to it last statement without returning a value (or alternatively, they used return; to exit from the middle without supplying a value), and they wrote the calls to the function such that those calls did not try to use the return value:
parse_input() /* similar to a procedure in Pascal, but fake! */
{
/* ... */
if (condition())
return; /* no value */
/* ... */
/* fall off end here */
}
int main()
{
parse_input(); /* no return value extracted, everything cool! */
return 0;
}
Unfortunately, some programmers also started not caring about the termination status of a program and writing main itself in this procedure style:
main()
{
/* do something */
/* fall off the end without returning a value */
}
(A mixed style also existed: omitting the int declarator but returning an integer value.)
These programs failing to return a value had an indeterminate termination status. To the operating system, their execution could look successful or failed. Woe to the script writer who tried to depend on the termination status of such a program!
Then things took a turn for the worse. C++ came along and introduced void, and it was adopted into C. With the void keyword in C++, one could declare a function that actually returns nothing (and make it an error to have a return; statement in any other kind of function). The dummy programmers who used to write main with no return type got dumber, and started sticking this new-fangled, fresh-out-of-C++ void in front:
void main() /* yikes! */
{
/* do something */
/* fall off the end without returning a value */
}
By this time they had forgotten that when they wrote main(), it actually meant int main(), which made the function have a compatible type with the startup call invoked by the environment (except for the matter of neglecting to return a value). Now they actually had a different function type from the expected one, which might not even be successfully called!
Where things stand now is that in C++ and in the latest C++ standard, main is still required to return an int. But both languages make a concession for the original dummy programmers: you can let execution "fall off" the end of main and the behavior is as if return 0; had been executed there. So this trivial program now has a successful termination status as of C99 and, I think, C++98 (or possibly earlier):
int main()
{
}
But neither language makes a concession for the second-generation dumber programmers (and everyone else who read the C books that those programmers wrote in the 1980's and since). That is, void is not a valid return declarator for main (except where it is documented by platforms as being accepted, and that applies to those platforms only, not to the portable language).
Oh, and allowance for the missing declarator was removed from C in C99, so main() { } is no longer correct in new dialects of C, and isn't valid C++. Incidentally, C++ does have such a syntax elsewhere: namely, class constructors and destructors are required not to have a return type specifier.
Okay, now about () versus (void). Recall that C++ introduced void. Furthermore, though C++ introduced void, it did not introduce the (void) argument syntax. C++ being more rigidly typed introduced prototype declarations, and banished the concept of an unprototyped function. C++ changed the meaning of the () C syntax to give it the power to declare. In C++, int func(); declares a function with no arguments, whereas in C, int func(); doesn't do such a thing: it declares a function about which we do not know the argument information. When C adopted void, the committee had an ugly idea: why don't we use the syntax (void) to declare a function with no arguments and then the () syntax can stay backward compatible with the loosey-goosey legacy behavior pandering to typeless programming.
You can guess what happened next: the C++ people looked at this (void) hack, threw up their arms and copied it into C++ for the sake of cross-language compatibility. Which in hindsight is amazing when you look at how the languages have diverged today and basically no longer care about compatibility to that extent. So (void) unambiguosly means "declare as having no arguments", in both C and C++. But using it in C++ code that is obviously pure C++ never intended to be C is ugly, and poor style: for instance, on class member functions! It doesn't make much sense to write things like class Foo { public: Foo(void); virtual ~Foo(void) /*...*/ };
Of course, when you define a function like int main() { ... }, the function which is defined has no arguments, regardless of which language it is in. The difference is in what declaration info is introduced into the scope. In C we can have the absurd situation that a function can be fully defined, and yet not declared, in the same unit of program text!
When we write main, usually it is not called from within the program, and so it doesn't matter what the definition declares. (In C++, main must not be called from the program; in C it can be). So it is immaterial whether you write int main() or int main(void), regardless of whether you're using C or C++. The thing which calls main does not see any declaration of it (that you write in your program, anyway).
So just keep in mind that if you write:
int main() /* rather than main(void) */
{
}
then although it is perfect C++ and correct C, as C it has a slight stylistic blemish: you're writing an old-style pre-ANSI-C function that doesn't serve as a prototype. Though it doesn't functionally matter in the case of main, you may get a warning if you use some compilers in a certain way. For instance, GCC, with the -Wstrict-prototypes option:
test.c:1:5: warning: function declaration isn’t a prototype [-Wstrict-prototypes]
Because -Wstrict-prototypes is a darn useful warning to turn on when programming in C, for improved type safety, (along with -Wmissing-prototypes), and we strive to eliminate warnings from our compile jobs, it behooves us to write:
int main(void) /* modern C definition which prototypes the function */
{
}
which will make that diagnostic go away.
If you want main to accept arguments, then it is int main(int argc, char **argv) where the parameter names are up to you.
In C++, you can omit parameter names, so this definition is possible, which serves nicely in the place of main().
int main(int, char **) // both arguments ignored: C++ only
{
}
Since the argument vector is null-pointer-terminated, you don't need argc, and C++ lets us express that without introducing an unused variable:
#include <cstdio>
int main(int, char **argv) // omitted param name: C++ only
{
// dump the arguments
while (*argv)
std::puts(*argv++);
}
first :
declares a function main - with no input parameters. Although main should have returns ( your compiler will take care of this )
2nd/3rd:
Declare a function main which returns an int and takes in no input parameters
You should use 3rd format. Rather this is the best way:
int main(int argc, char *argv[]){
return 0;
}
You should use 1 one of these 4 choices:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);
where it's conventional to use the names argc and argv; you can change them but don't.
Take care never to use void main(void); which is too-often seen in production code.
By default main function returns an integer type, hence its "int main()" or you can give simply "main()"
"main(void)" is same as "main()", it tells the compiler that main function has no arguments.
In case if you want to pass arguments via main function:
int main(int argc, char *argv[]){
return 0;
}
main(){}
The above line give you an error. The default return type of any function in c is int. As the above code return nothing it gives you an error.
int main(){
//body
return 0;
}
In above code it fulfill all requirement so the above code will run.In above code we pass no argument in the function. So this function can take global and local variables to process.
int main(void)
{
//code
return 0;
}
In above code we pass no argument in the function. But specifying void tells the compiler that it does not take any argument. void is the default datatype of argument that signifies no input.

Can you pass a function with a variable amount of arguments as an argument to another function in C?

Related to [question]: How do you pass a function as a parameter in C?
Is it possible in C to pass a function that has a variable number of arguments to another function? If so, could someone point me to some documentation or fill me in? Thanks.
You can't pass a function (of any sort) as a parameter, but you can pass a pointer to a function (again, of pretty much any sort). It's usually easiest to use a typedef:
typedef int (*fptr)(char const *, ...); // e.g., match with `printf`
int apply(fptr f, char const *a, int b) {
return f(a, b);
}
You can make a function pointer, e.g.:
typedef int (*vafunc)(const char *, ...); // like printf
However, you cannot really forward the arguments, i.e. the following doesn't exist in standard C:
void call_other(vafunc f, const char * fmt, ...)
{
// want to say:
// f(fmt, ...); // How to write this???
}
GCC offers such anonymous argument forwarding as an extension, but it's not possible in standard C. You're typically expected to match each variadic function with a v... counterpart that takes a va_list argument, precisely for this purpose. (Calling f with a fixed number of arguments is possible, of course: f("abc", 1, 2, 3);)
http://www.lemoda.net/c/function-pointer-ellipsis/index.html seems to be what you seek.
You can pass a varargs function the same way as you would another function.
Here's a short test program that demonstrates passing a varargs function as a parameter:
int bar(int x, ...) {
/* In a real program, you would actually use the arguments beyond x */
return x;
}
int foo(int (*baz)(int, ...)) {
return bar(10, "ABC");
}
int main(void) {
printf("%d\n", foo(bar));
return 0;
}
It prints 10, as you might expect.
N.B. You can't actually pass a function as an argument to another function in C - instead, you can pass a function pointer, which points to the actual function as loaded from the executable. This is weaker than the first-class status of functions in functional programming languages, or even than the status of a delegate in some object-oriented languages like C#. For instance, you can't create a function on the fly in C.
Sure. They're called "variadic functions".
1) Just use an "ellipses" ("...") as the last argument in your function prototype
2) In order for the called function to "know" how many arguments were passed to it, use the macros "va_start" and friends in "stdargs":
3) 1) and 2) above are simply to have a function that has a variable #/arguments. You can also have a function pointer with a variable #/arguments. Do the same thing - just include the ellipses ("...") in your function prototype, and use "stdargs" in your function implementation.

Using "void" in C

I'm confused about why we need to pass void into C functions:
int f(void) { return 0; }
versus
int f() { return 0; }
What is the proper thing to do and why?
In C, int f() is an old-style declaration. It says that f expects a fixed but unspecified number and type(s) of arguments. For example, given int f() { return 0; }, the compiler won't complain about f(42), or f("hello, world") (though the behavior of such a call is undefined).
int f(void) explicitly says that f takes no arguments.
(C++ has different rules; Stroustrup wasn't as concerned about backward compatibility with old C code.)
It's a vestige of C.
f(void) takes no arguments, so f(1) is invalid.
f() means that the parameters are unspecified, so f(1) is valid here.
The void in this case just means "there are no parameters." I'm not sure whether your second case will compile, but either way I'd prefer the first case just to be as clear as possible. Of course, when calling f, you just use the empty parentheses:
int x = f();

How can c let a function declaration with any parameter type?

I forgot to write void parameter but it works the i put void it gives error
it lets this:
print(int size,int table[size][size]){
int i,j;
printf("-------TABLE-------\n");
for(i = 0;i<size;i++){
for(j = 0;j<size;j++){
if(table[i][j]==EMPTY)
printf(". ");
else
printf("* ");
}
printf("\n");
}
}
it says"previos implicit declaration was here " (means the call in main)
void print(int size,int table[size][size]){
int i,j;
printf("-------TABLE-------\n");
for(i = 0;i<size;i++){
for(j = 0;j<size;j++){
if(table[i][j]==EMPTY)
printf(". ");
else
printf("* ");
}
printf("\n");
}
}
If you declare a function
foo(int x) {
}
the compiler will infer the return-type to be int, as if you had written
int foo(int x) {
}
But, really, that's the least of your problems.
Reference: §1.3.1 of The C Library Reference Guide by E. Huss
It's a historical artifact. This happens for backwards compatibility with old C code (from before C was standardized). Functions without explicit return types are assumed to return int, and if no explicit parameters are specified, it's assumed to take some unspecified number of arguments.
In C, in contrast to C++, and assuming you are not using a strict C99 conformance mode in your compiler, then when the compiler comes across something that looks like a function call but the identifier has not previously been declared, then the compiler assumes that it is the name of a function returning an integer.
int main(void)
{
something_functional(1, 2);
}
Without a prototype, the compiler in C90 or relaxed C99 mode will assume that 'something_functional()' is indeed a function returning an integer.
If you subsequently write:
something_functional(double d, char *s)
{
...
}
The compiler will assume that the return type of 'something_functional()' is an int and will let the code compile (despite the horrendous mismatch between the actual argument types in the call and in the function definition).
If you subsequently write:
void something_functional(douebl d, char *s)
{
...
}
the compiler will, quite correctly, complain that you've told it different things about the function and that makes it erroneous.
There are several ways to fix the problem:
Move the function definition ahead of the function call. This is what Pascal required, and leads to the main() function appearing at the bottom of the file.
Place a prototype for the function ahead of its use in the file:
static void something_functional(double d, char *s);
I take the view that if the function is not going to be called from outside the source file, it should be static.
Note that C99 in a strict conforming mode does not allow you to declare functions implicitly. C++ never has either.
There's another interesting feature of pre-C99. You could also write:
static c;
static function();
some_function(a, b)
{
}
This defines an integer variable c, a function called function() that returns an int, and a function called some_function() that takes two int arguments and returns an int.
This is not allowed in strict C99 code - and was not particularly good style in C90 code, but was allowed for backwards compatibility with pre-standard C.
without void eg, function() says the function declaration might have any parameters.
function(void) says that it has precisely none.

Resources