Differing function prototypes and definitions

C

Christopher Key

Hello,

I've a couple of situations where I'd like to have a function prototype
in a public API differing from the function definition.

Firstly, the API defines a callback function,

typedef void (*mycb)(int x);

Now, clients of this library might want to declare x as const in order
to add some compile time checking to their code. Clearly, their doing
this won't affect the library, nevertheless one compiler (although I'm
afraid I can't remember which it was) did issue a warning.


Secondly, the API defines a function,

void myfn(int *const x[]);

This is prototyped in this form, firstly because it best describes how x
is used, and secondly because it matches the actual form of the callback
mentioned above, which is closer to,

typedef void (*mycb)(int *const x[]);


Now, in order to add some compile time checking to my code, the function
is declared as,

void myfn(int *const *const x)

to stop me accidentally modifying x. Again, this change is entirely
irrelevant for the client, but I still get warnings about this.


I know that compilers are allowed to emit whatever diagnostics they
like, and the fact that this generates a warning is no indication of a
problem. Essentially what I'd like to know is whether doing this is:

1) Legal C and standard pratice
2) Legal C but bad practice
3) Illegal C


Regards,

Chris
 
J

Jack Klein

Hello,

I've a couple of situations where I'd like to have a function prototype
in a public API differing from the function definition.

Firstly, the API defines a callback function,

typedef void (*mycb)(int x);

Now, clients of this library might want to declare x as const in order
to add some compile time checking to their code. Clearly, their doing
this won't affect the library, nevertheless one compiler (although I'm
afraid I can't remember which it was) did issue a warning.

Let me get this straight, you have a header with a prototype:

typedef void (*mycb)(int x);

....your user includes this header and has this code:

void my_func(const int x);
mycp func_ptr = my_func;

....and his compiler generates a warning? If so, I would say this is
noise, top level const is meaningless in this case. I'd discuss this
with the compiler vendor.

6.7.5.3 Function declarators (including prototypes), P15, last
sentence:

"In the determination of type compatibility and of a composite type,
each parameter declared with function or array type is taken as having
the adjusted type and each parameter declared with qualified type is
taken as having the unqualified version of its declared type."

So the user's function my_func() is a compatible type with your
function pointer.
Secondly, the API defines a function,

void myfn(int *const x[]);

This is prototyped in this form, firstly because it best describes how x
is used, and secondly because it matches the actual form of the callback
mentioned above, which is closer to,

typedef void (*mycb)(int *const x[]);

Now, in order to add some compile time checking to my code, the function
is declared as,

void myfn(int *const *const x)

to stop me accidentally modifying x. Again, this change is entirely
irrelevant for the client, but I still get warnings about this.

What warnings? Copy and past the text. Personally, I never liked the
idea of top level const in function parameters.
I know that compilers are allowed to emit whatever diagnostics they
like, and the fact that this generates a warning is no indication of a
problem. Essentially what I'd like to know is whether doing this is:

1) Legal C and standard pratice

Whose standard practice?
2) Legal C but bad practice

What is your definition of "bad practice"?
3) Illegal C

In future, please set your newsreader to post a proper signature
delimiter, which consists of the string expressed as "-- \n" in C
notation.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
C

Christopher Key

Jack said:
Let me get this straight, you have a header with a prototype:

typedef void (*mycb)(int x);

...your user includes this header and has this code:

void my_func(const int x);
mycp func_ptr = my_func;

...and his compiler generates a warning? If so, I would say this is
noise, top level const is meaningless in this case. I'd discuss this
with the compiler vendor.

6.7.5.3 Function declarators (including prototypes), P15, last
sentence:

"In the determination of type compatibility and of a composite type,
each parameter declared with function or array type is taken as having
the adjusted type and each parameter declared with qualified type is
taken as having the unqualified version of its declared type."

So the user's function my_func() is a compatible type with your
function pointer.

Apologies for the noise, this case was just me being braindead. The
client code had ended up with:

void my_func(cont int x);

....

void my_func(int x) {
...
}

Secondly, the API defines a function,

void myfn(int *const x[]);

This is prototyped in this form, firstly because it best describes how x
is used, and secondly because it matches the actual form of the callback
mentioned above, which is closer to,

typedef void (*mycb)(int *const x[]);

Now, in order to add some compile time checking to my code, the function
is declared as,

void myfn(int *const *const x)

to stop me accidentally modifying x. Again, this change is entirely
irrelevant for the client, but I still get warnings about this.

What warnings? Copy and past the text. Personally, I never liked the
idea of top level const in function parameters.

The exact code is as follows:

decoder.h (public header file):
....
hdcd_bool hdcd_decoder_process_buffer(hdcd_decoder *const hdcd, int32_t
*const input_buffer[], const size_t samples);


hdcd.c:
....
hdcd_bool hdcd_decoder_process_buffer(hdcd_decoder *const hdcd, int32_t
*const *const input_buffer, const size_t samples) {
...
}

and MSVC emits:
..\hdcd.c(240) : warning C4028: formal parameter 2 different from declaration

I prefer the public prototype to be 'int32_t *const input_buffer[]' as
it best describes the intention of the parameter, and matches similar
APIs (e.g. FLAC). However, I was wanting the final const in the
function definition, both to prevent me from doing something
unintentional with the passed parameter, and also because it might buy
some execution efficiency from the compiler.
Whose standard practice?


What is your definition of "bad practice"?

Okay, a fairly vague question. What I meant by 'legal C nut bad
practice' was things like e.g. casting the return of malloc, writing <<1
when you really mean *2 etc. They'll do what you want, but might hide
potential bugs and make your code harder to follow. The other two cases
I hope follow from the above.

In future, please set your newsreader to post a proper signature
delimiter, which consists of the string expressed as "-- \n" in C
notation.

Hopefully now fixed, thanks.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top