This question already has answers here:
How to achieve function overloading in C?
(14 answers)
Closed 3 years ago.
Is it ok to leave the parameters unused?
I'm trying to run the function like this:
void encoder();
void encoder(int argc, FILE* inputFP, FILE* outputFP);
Is there a need for a second function, one for dealing with stdio and one for dealing with files? When I try to run
void encoder(int argc, FILE* inputFP, FILE* outputFP); without any arguments I get errors:
error: too few arguments to function ‘void encoder(int, FILE*, FILE*)’
encoder();```
Is it ok to leave the parameters unused?
No, all arguments must be present and correct.
You should also be careful that you do not provide different prototypes for a function (or any symbol) within a given application.
If you really want to call it with no arguments, then the best approach is to have two functions and call the one you're after:
void encoder(void) {
encoder2(0, stdin, stdout);
}
void encoder2(int argc, FILE* inputFP, FILE* outputFP) {
/* ... */
}
If you want to have a variable number of arguments, then you could look at using the macros in stdarg.h (like printf() and friends), though you still won't be able to get away with zero arguments, and you'll need to be very careful with your usage.
As you've discovered, no it's not valid.
C lacks the support for default values, so the arguments would be quite useless. The solution to this particular problem is to use magic FILE * "files" that map to the standard input/output channels, i.e. stdin and stdout from <stdio.h>.
Related
This question already has answers here:
C function syntax, parameter types declared after parameter list
(7 answers)
Should I place the parameter storage class specifier in the function definition or in both the declaration and definition?
(5 answers)
"register" keyword in C?
(19 answers)
Closed 2 years ago.
void
usage (cpp)
register const char *const *cpp;
{
(void) fprintf (stderr, *cpp++, program_name, cvs_cmd_name);
for (; *cpp; cpp++)
(void) fprintf (stderr, *cpp);
error_exit ();
}
I don't get why register variable is not inside the curly brackets and what is this (void) in front of fprintf? Also register const char *const *cpp, i've never seen anything like this before
The reason you've "never seen this before" is because this is using the syntax of the original, historical, K&R C version. That must be some real, old C code you're looking at. I just looked up, and ANSI C (C90) came out in 1990, so this code must be at least 30 years, or so, old.
I suppose this is something that needs to be known if one needs to deal with historic C code, but otherwise you can simply forget it.
The (void) cast means the same thing it means today.
The register keyword is a hint to the compiler that you'd like that value to be kept in a dedicated register on the processor. This can speed up reads and writes. With modern compilers, however, this sort of optimization is not only unnecessary but often counterproductive.
The reason it is between the function declaration and the block is that in old c (pre C90) you wouldn't declare parameter type next to the parameter but between the declaration of the function and the block.
For example:
int main(argc, argv)
char ** argv;
{
...
}
Notice I didn't do anything for argc because if you don't explicitly define a type it defaults to int.
You'll see this more often than you'd think. I ran into this a bunch when I did work on FFMPEG.
The (void) cast thing prevents unused parameter warnings/errors. I've run into this when working on PortAudio with a low-level callback function.
This question already has answers here:
Macro returning the number of arguments it is given in C? [duplicate]
(3 answers)
Closed 4 years ago.
It might be impossible to do but can we actually get the number of arguments a function's wants in C?
The goal is to make a function named call that requires a function's pointer and some arguments. But because we can't count the number of arguments in a variadic arguments function, I want to count how many arguments does the function's pointer requires.
Here's how I want to create it:
void func(int a, int b, char* c) {
// Do things
}
int call(void *f, ...) {
// Find how much arguments *f wants and loop over the variadic args
}
int main() {
call(func, 1, 2, "hello");
}
By the way, it needs to be at run-time.
Nothing in the C standard provides a facility for ascertaining the number of arguments a function requires, other than the fact that C implementations are free to provide extensions.
This question already has answers here:
How to wrap printf() into a function or macro?
(8 answers)
call printf using va_list
(4 answers)
Closed 4 years ago.
I am working on making a version of printf in an embedded system that will print over a variety of interfaces. I am using snprintf to create the string and then sending it out over the interface. My curiosity is what the "..." being passed into the function is. The printf that I am using looks like, this is taken from an embedded printf library
void u_printf(const char* format, ...)
In this case the ... is some number of assorted variables passed into the function. But if I want to write my own version of this how do I get those variables passed in so I can then pass them on to snprintf.
void u_printf(const char* format, ...){
int cx;
char buffer[100];
cx = x_snprintf(buffer, 100, format, ??);
// function to send buffer to interface goes here
}
So how do I go about getting the ... variables passed in to where the ?? mark is? Thanks!
Some quick help revealed that va_list is the answer here. When the ... is present we can grab the arguments passed in by creating va_list va variable. This can then be used or passed to vsnprintf()
Recently I got a question when writing a program for file opening.
Let me explain my question clearly. Here I'm taking open call as an example.
To create a file:
open("file_name", O_CREAT, 0766); //passing 3 parametrs
To open a file:
open("file_name", O_RDWR); //only 2 arguments.
Then I clearly observed this point and it also works for main() too.
main(void) //worked
main(int argc, char **argv); //worked
main(int argc) //worked and it's doesn't give an error like "too few arguments".
main() //worked
So how we can create these optional arguments? How exactly can the compiler validate these prototypes? If possible, please write an example program.
The open function is declared as a variadic function. It will look something like this:
#include <stdarg.h>
int open(char const * filename, int flags, ...)
{
va_list ap;
va_start(ap, flags);
if (flags & O_CREAT)
{
int mode = va_arg(ap, int);
// ...
}
// ...
va_end(ap);
}
The further arguments are not consumed unless you have indicated that they do in fact exist.
The same construction is used for printf.
The manual doesn't always make this explicit, since the only possible two signatures are (char const *, int) and (char const *, int, int), so there's little point in revealing that you the function actually accepts variable arguments. (You can test this by trying to compile something like open("", 1, 2, 3, 4, 5, 6).)
In all cases, a varargs function must be able to determine somehow, from the fixed arguments, how many variable arguments there are. For example, the printf() family of functions use the format string to determine the number and types of the arguments. The execl() function uses a sentinel (null pointer) to mark the end of the argument list. It would be possible to use a count instead of a sentinel (but if you're going to do that, the chances are that a count and an array in a non-varargs function would work as well as, if not better than, a count and a list of arguments). The open() function uses one of the flag bits to determine whether the mode should be present — see Kerrek SB's answer.
The main() function is a special case. The implementation (compiler) is prohibited from declaring a prototype for it, and must accept at least the two forms:
int main(int argc, char **argv);
int main(void);
or their equivalents. It may accept other forms too; see What's the use of the third environment variable in the C main()? for one common form. In C, but not C++, a standard compiler can document other return types — and Microsoft has documented void as a valid return type from VS 2008 onwards.
Because there is no implementation-provided prototype for main(), the compiler can't officially reject any declarations/definitions of main(), though it might pass comment on forms it doesn't recognize (GCC does comment on main() functions that do not return an int type, for example).
This question already has answers here:
What should main() return in C and C++?
(19 answers)
Closed 7 years ago.
Can anyone tell me the difference between int main() and int main(void)? Why do both of them work and what is the default argument to int main()?
No difference under ordinary circumstances. This is no 'default argument to main()', since it has no arguments at all.
Here's the un-ordinary circumstance. If you write your own call to main, then () will permit you to pass it any parameters you like, while (void) will force you to pass it none. Still, none of this matters in terms of the 99.99999999% case, which is main being invoked by the runtime to launch your program. The runtime neither knows nor cares if you write () or (void).
If you code the standard int main(int argc, char **argv) you will get your command-line parameters in there.
main() allows you to call main with any number of parameters. main(void) forces you to call main with no parameters. So:
main(foo, bar);
Is fine with main() but not with main(void) - the compiler generates an error.
Now if you're specifically asking about the program's entry point, it doesn't really make a difference; in either case, you won't have the arguments to the program (argc, argv, envp) available.
From a practical viewpoint, there's no real difference. With int main(void), you're explicitly stating that main takes no parameters, so you can't invoke it with any. With int main(), you're leaving open the possibility of invoking main with some parameters.
However, except in strange situations like code golf or intentionally obfuscated code, you don't invoke main anyway -- it's the entry point to the program, so it's automatically invoked by the startup code. The startup code will pass the command line arguments anyway, so your choices don't change how it's invoked, only whether you use or ignore the parameters that get passed.
The standard does specifically allow you to define main with or without parameters (§5.1.2.2.1/1):
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;
Though it's outside the tags specified, in C++ the situation is slightly different. In C, a function declaration like:
int f();
specifies that f is a function returning an int, but gives no information about the number or type of parameters f might expect (this is included primarily for compatibility with old code -- at one time, this was the only way to declare a function in C). In C++, that same declaration explicitly declares f as a function that takes no parameters, so attempting to invoke f with one or more parameters cannot invoke this function (it must either invoke another overload or produce an error if no suitable overload is found).