Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I'm going through K&R and I'm on the functions chapter, and I have a quick question:
Do I always have to declare functions as prototypes? What decides what kind of arguments will be in the prototype? Can it just be two variables in the function definition?
Thanks!
You should always declare and define your functions using prototype syntax; doing so allows the compiler to catch errors where you pass the wrong number or types of arguments in the function call. C still supports declarations and definitions that don't use prototype syntax, but that's only to support ancient code bases; you should not write new code using the old syntax.
As for what arguments go into the prototype, that depends entirely on what the function needs to do. Suppose I'm writing a replacement for the pow() function in the math library. I need 2 arguments, one being the base and the next being the exponent:
double myPow( double base, int exp ); // declaration, prototype syntax
...
double myPow( double base, int exp ) // definition, prototype syntax
{
...
}
You can omit the parameter names in the declaration:
double myPow( double, int );
What matters is that the number and types of the arguments is specified.
The old-style declaration and definition would look like this:
double myPow( ); // declaration, old syntax
...
double myPow( base, exp ) // definition, old syntax
double base;
int exp;
{
...
}
The only time you don't choose the arguments for a function you're defining is the main function; while you get to define the implementation of main, you do not get to decide what arguments it will take. main either takes no arguments:
int main( void )
or two arguments of type int and char **:
int main( int argc, char **argv )
An implementation may provide additional prototypes for main (such as a third char **envp argument found on some Unix implementations), but that's limited to the implementation - you are not allowed to create an arbitrary interface for main.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 days ago.
The community is reviewing whether to reopen this question as of 4 days ago.
Improve this question
I'm learning C language and I bumped into a line that is like the following one:
void myControl(const myInput*, myOutput*, myRuntime*, const myConfig*);
what does the * symbol mean after the variables?
I looked for 'C language * meaning' in the internet but I always find * as the symbol for the pointers that is placed before and not after a variable name.
In the line:
void myControl(const myInput*, myOutput*, myRuntime*, const myConfig*);
myControl is a function that takes 4 parameters.
The function does not return a value.
Each of the parameters is a pointer to a type (presumably a structure). Some of the structures are const (unchangable). Some of the structures can be changed.
The full function prototype in the conventional form with the parameter names would look like:
void myControl(const myInput* inputData, myOutput* outputData, myRuntime* runTimeInfo, const myConfig* configuration);
parameter inputData is a pointer to a structure of type myInput.It cannot be changed.
parameter outputData is a pointer to a structure of type myOutput.It can be changed.
parameter runTimeInfo is a pointer to a structure of type myRuntime.It can be changed.
parameter configuration is a pointer to a structure of type myConfig.It cannot be changed.
The line
void myControl(const myInput*, myOutput*, myRuntime*, const myConfig*);
is a function declaration.
Until C23, one of the key syntactical differences between a function declaration and a function definition, is that in a function declaration the identifier (what you refer to as the "variable name") of each parameter in the parameter list is optional.
On the other hand, the identifier of each parameter is required in a function definition:
void myControl(const myInput* input, myOutput* ouput,
myRuntime* rt, const myConfig* config)
{
/* use the arguments, etc. */
(void) input;
(void) output;
(void) rt;
(void) config;
}
(C23 will introduce unnamed parameters in function definitions to the language.)
What you see in the example are simply the types that form the function's signature, where each parameter is a pointer type as indicated by the * symbol.
This question already has answers here:
Is it better to use C void arguments "void foo(void)" or not "void foo()"? [duplicate]
(6 answers)
Closed 6 months ago.
So I get that a void function won't return a value, while a int one for example will return an integer. So void main(){} doesnt return, but int main(){return 0;} will return.
My question is, what is the difference between these 3 functions. I know the first one wont return a value, the second one will return an integer. But how about the third one? I know it returns an integer because I've tested it, so what does that (void) does? Why is is there?
void main(){}
int main(){return 0;};
int main(void){return 0;};
I'm a begginer so sorry if it sounded confusing... Thanks in advance!!
(The question is about the programming language C)
Between the parenthesis are the parameters to the function.
In a function definition, the proper way to designate a function that takes no parameters is to simply specify void for the parameter list.
An empty parameter list (in a definition) is also a way of saying the function takes no parameters, however this syntax is considered deprecated and should not be used in new programs.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
What are the practical applications of compound literals? I am not quite sure how an address of an unnamed region of storage could be useful.
int *pointer = (int[]){2, 4};
I found them mentioned here: https://en.cppreference.com/w/c/language/compound_literal
Here are some great ones:
Working around interfaces that take a pointer to input rather than a value (possibly to return an updated value you don't have any reason to care about):
y = accept(x, &sa, &(socklen_t){sizeof sa});
Implementing functions with named and default-zero/null arguments:
#define foo(...) foo_func(&(struct foo_args){__VA_LIST__})
foo(.a=42, .b="hello" /* .c = NULL implicitly */);
Implementing custom formats for printf (automatically getting per-macro-instantiation temp buffer):
#define fmt_mytype(x) fmt_mytype_func((char[MAX_NEEDED]){""}, x)
printf("...%s...", ..., fmt_mytype(foo), ...);
Compound literals can be used for arrays, but they are just as useful to initialize structs, allowing you to put a complicated initializations in one line, making the code easier to read, and less tedious to write.
Like so:
typedef struct{
int a,b,c;
char *d;
}type;
int main(){
type t=(type){.a=0,.b=1,.c=2,.d="Hello world"};
...
Without a compound literal that would have been at least four lines of code.
They can also simplify transformation functions:
typedef struct{
int a;
int b;
}twoInts;
twoInts swap(twoInts in){
return (twoInts){.a=in.b,.b=in.a};
}
They can be useful when you don't have control over the left part. If possible, you would probably use int pointer[] = {2, 4};. But what if the left part is defined by e.g. an external API, and you want to assign to it? The compound literal would be an option.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
People have marked this post as a duplicate of this but it's actually not because I'm not asking what is a composite type but what is its purpose and i gave a use case where it could cause a harm for software developers and then asked if this should be undefined behavior instead.
I was reading that part of the C11 standard about composite types and i was just like : Why the heck on earth would someone do something like that ?
I mean i can't see anything interesting about that. I think this is very confusing for programmers. For the sake of example, let's say we had a function void f() that people used everywhere in the software, they just declare extern void f() and use it. The definition of the function is somewhere programmers don't care about; then one day, one smart guy needed to add an argument to that function and changed the definition to something like void f(int *ptr) {/* ..*/ return *ptr;}. The software will still compile happily but god, all that legacy code that used the old interface is screwed up with segfaults.
The code below is a demo :
/* main.c */
#include <stdio.h>
int f ();
int p = 5;
int main ()
{
int r = f (); /* This call will cause segfault */
int s = f (&p);
printf ("r=%d / s=%d \n", r, s);
return 0;
}
/* another_unit.c */
int f (int *ptr)
{
return *ptr;
}
I don't see the purpose of such a thing. In my opinion that should be undefined behavior or at least why do compilers like GCC don't say anything about it ?
The point in your example is that the function f() has no prototype, and the other one has one. The form of declaration without comes from early C and is marked as obsolete since many years.
The construct of composite type between the two helped when prototypes were introduced into C to accommodate between old code and new code.
Calling a function with arguments that do not correspond to the parameters that it expects has undefined behavior, so with that mechanism you have to know what you are doing.
In short, don't use declarations without prototype. They are outdated since long and might be removed from the C standard at any time.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Why we use a semicolon after the int add(int,int) statement in second line.
#include<stdio.h>
int add(int,int);
int main()
{
int a,b,c;
scanf("%d %d",&a,&b);
c=add(a,b);
printf("The sum of the 2 numbers is %d",c);
return 0;
}
int add(int x,int y)
{
int sum;
sum=x+y;
return sum;
}
In the C grammar declarations are defined the following way
declaration:
declaration-specifiers init-declarator-listopt ;
^^^
As you can see the semicolon is required.
And this
int add(int,int);
is a function declaration. Thus you have to place a semicolon at the end of the declaration.
Compare two programs
int main( void )
{
int add( int x, int y )
{
//...
}
}
and
int main( void )
{
int add( int x, int y );
{
//...
}
}
The first program is invalid because the compiler will think that the function add is defined within function main.
The second program is valid. There is a function declaration and a code block within main.
So semicolons are needed that to distiguish declarations from other program constructions.
int add(int, int);
This is a forward declaration - it's a way of telling the compiler "there's a function called 'add' that takes two ints, so if you see me using it just trust me, I'll define it later". Because you're not defining it yet, you don't need the {} curly braces after it. The semicolon appears at the end of every line of code in C, except for after certain braces (e.g. if statements, function definitions). So a semicolon is still needed after a forward declaration.
Semicolons end statements in C. So the semicolon tells C that the statement to declare the add function has been terminated, and whatever follows is a new statement.
In this case, this is a function declaration and the semicolon states that there is nothing more to be expected. Without the semicolon, a function definition would be expected with the curly braces as in main() {...}
Without the semicolon, the compiler is expecting a function definition (starting with an open brace), or a comma to separate the one definition from the next.
The semicolon is just a terminating character. As no body to the function is defined (e.g. unlike main() { ... } ) it is a way of letting the compiler know not to expect anything else.
It is important to understand what is declaration and definition in C/C++. When you declare a variable or function, you are telling the compiler there is something with the name whose type is specified. The compiler does not have to get its full definition of the variable or function.
In the example, the function is firstly declared and then defined. The syntax of declaration statement should include a semicolon.
You can get more clear concepts by reading this: http://www.cprogramming.com/declare_vs_define.html
The historical reason this was necessary is that, originally, in K&R C, add() would have been written:
int add()
int x;
int y;
{
return x+y;
}
Without a semicolon after the prototype, it would be hard to impossible to distinguish this from:
int add();
int x;
int y;
{
/* A nested block. */
}
Remember that the C pre-processor is one-dimensional and turns the program into a list of tokens separated by whitespace. The parser can’t see newlines or indentation to guess what you meant.
Plus, statements in C generally end in semicolons and it’s easier to be consistent than to make programmers remember a bunch of arbitrary exceptions.