views:

2186

answers:

3

I was wondering about little differences between declaration of function prototypes in headers and in .c files. I have a header with some prototype functions and a some .c files with real implementation of these functions. I made some changes in the header, only added "__restrict" qualifier (recognized by gcc). My question is do I have to put the "__restrict" qualifier in .c files to (currently the code compile so I guess the answer is no, but some precision would be appreciated).

Does this work for every C qualifier? Can I add some "const" or "volatile" in header without having to do the same in .c files?

currently in header :

int myfunc_gettype (const mytype *__restrict, int *__restrict);

and in implementation file :

int myfunc_gettype(const mytype *attr, int *type)
+6  A: 

You must. The mismatch invokes undefined behavior. Is there some reason why you want to have separate declarations in the header and at definition?

Note well, that the keyword is restrict as opposed to __restrict which is a vendor extension (hint: look at the _'s before the keyword name). You should stick to the standard version for portability.

dirkgently
in fact the restrict keyword is C99 and the __restrict is just catch by gcc with i guess the same result.
claferri
I'm not sure to understand, if I have the restrict qualifier in the header and not in the implementation, will the pointer be "restrict" anyway or not?
claferri
You are invoking UB. It may actually cause the pointer to be restrict qualified. The standard C++ keyword is 'restrict', why use __restrict?
dirkgently
The restrict keyword is a type qualifier for pointers and is a formal part of the C99 standard.In code that cannot be compiled with C99, use either __restrict or __restrict__ to enable the keyword as a GCC extension.
claferri
What is "UB" ?
claferri
I have one header file for my library and one .c file per function so I was just wondering if I can avoid modifying every .c files (which is a lot of files) and just modify the header only.
claferri
UB = Undefined Behavior -- a malformed program (and much worse). No, can't be that lazy :)
dirkgently
Note well: Since it invokes UB, the compiler is not supposed to produce a diagnostic. Don't fall for this, though.
dirkgently
Why not use gcc -std=c99?
dirkgently
@dirkgently : because my code isn't C99 yet :)
claferri
@dirkgently : I'm no that lazy, but I tried to compile after editing just the header and as it compile, I just asked myself this question :)
claferri
@claferri: When you rely on vendor extensions, you lose portability. (That bit about laziness was just a joke. No offense, please!)
dirkgently
@dirkgently : you must be right about portability issue, I'm going to see if I can have C99 code instead of using __restrict, and i'm not offensed of course ;)
claferri
A: 

NOTE: You haven't actually added the 'restrict' qualifier. You just have different (optional) variable names in the prototype.

As to your question, most good C compilers will catch this bug and throw a warning/error if the non-matching prototype is #included with the implementation. If you have mismatching prototypes, you may see problems ranging from subtle to instant crash.

HUAGHAGUAH
you mean __restrict is an optional variable name in the prototype? I'm pretty sure you're wrong with gcc.
claferri
In fact, I was right : "The restrict keyword is a type qualifier for pointers and is a formal part of the C99 standard.In code that cannot be compiled with C99, use either __restrict or __restrict__ to enable the keyword as a GCC extension."
claferri
Since it compiles, it must be just a qualifier; you can't have two arguments with the same name. I wondered at first, but I think this argument is decisive - assuming the code does compile as claimed.
Jonathan Leffler
@Jonathan : yes, before using the __restrict qualifier, I first used restrict without -std=c99 and gcc complain about having two arguments with the same name, then i remember i couldn't compile with -std=c99 for the moment and decided to use gcc extension __restrict instead.
claferri
A: 

With gcc 4.0.1, it depends on whether the const is pointless:

// Who cares, compiles fine, but irks the maintenance programmer.

// f.h
int f(const int i);

// f.c
int f(int i) { return i += 42; }


// No no no no Your Types Conflict gcc will not stand for it

// f.h
int f(const int *pi);

// f.c
int f(int *pi) { return (*pi)+= 42; }
Thomas L Holaday
It even irks the SO community enough to provoke a downvote.
Thomas L Holaday
The question wasn't "is this legal" or even "is this acceptable practice"; it was "will it work."
Thomas L Holaday