"Homemade" C99 prototype?

R

Robert Latest

Hello,

generally I stick with C89, but C99 is useful at times, such as the
snprintf() function.

To use that function within an otherwise C89-conforming program, I just put
the proper prototype into my program. The linker links against the C99
library, so everything runs through without error or warning. My question
is: Is this good practice?

I can't see any problems because:

1. CC without C99 header, LD against C99 lib -> no problem
2. CC with C99 header, LD against C99 lib -> no problem
3. CC with with non-standard header (snprintf() defined
in some other way) -> compiler error
4. CC without non-standard header, LD against non-standard
lib -> runtime error

Only the last case is a problem, but that would be such a profoundly goofy
implementation of some non-C language that I wouldn't have to worry about
it.

Am I right?

robert
 
E

Eric Sosman

Robert said:
Hello,

generally I stick with C89, but C99 is useful at times, such as the
snprintf() function.

To use that function within an otherwise C89-conforming program, I just put
the proper prototype into my program. The linker links against the C99
library, so everything runs through without error or warning. My question
is: Is this good practice?

I can't see any problems because:

1. CC without C99 header, LD against C99 lib -> no problem
2. CC with C99 header, LD against C99 lib -> no problem
3. CC with with non-standard header (snprintf() defined
in some other way) -> compiler error
4. CC without non-standard header, LD against non-standard
lib -> runtime error

Only the last case is a problem, but that would be such a profoundly goofy
implementation of some non-C language that I wouldn't have to worry about
it.

In case 2, I think you'll need not only a C99 <stdio.h>
but also a C99 compiler, because a C90 compiler will choke
on the `restrict' keyword. Also, the <stdio.h> declaration
will use `restrict' but your free-hand version presumably
will not, so the declarations of snprintf() conflict with
each other. (Well, they are at least "different." A brief
scan of a few sections of the Standard leaves me baffled as
to whether the declarations "conflict" strongly enough to
require a diagnostic; let's leave it to the language lawyers.)

I can't think of a really "good" way to solve the problem
completely, but adding a guard like

#if __STDC_VERSION < 199901L
int snprintf(char *, size_t, const char *, ...);
#endif

.... may smooth over a few rough spots.
 
M

Malcolm McLean

Robert Latest said:
generally I stick with C89, but C99 is useful at times, such as the
snprintf() function.

To use that function within an otherwise C89-conforming program, I just
put
the proper prototype into my program. The linker links against the C99
library, so everything runs through without error or warning. My question
is: Is this good practice?
No. It won't compile unless a C99 library is present.
The correct way to solve the problem is to write a function that calculates
the maximum length of a printf()-style format string. You then use that to
ensure vsprintf() doesn't overflow its buffer.
 
D

David Thompson

Robert Latest wrote:
In case 2, I think you'll need not only a C99 <stdio.h>
but also a C99 compiler, because a C90 compiler will choke
on the `restrict' keyword. Also, the <stdio.h> declaration
will use `restrict' but your free-hand version presumably
will not, so the declarations of snprintf() conflict with
each other. (Well, they are at least "different." A brief
scan of a few sections of the Standard leaves me baffled as
to whether the declarations "conflict" strongly enough to
require a diagnostic; let's leave it to the language lawyers.)
Not. Multiple (co-visible) declarations of the same function must give
it _compatible_ types, and for function types in 6.7.5.3p15 among
other things: "(In the determination of type
compatibility ... each parameter declared with qualified type
is taken as having the unqualified version of its declared type.)"

This is because arguments are passed by (r)value in C, and the
original (C89) qualifiers (const, volatile) don't apply to rvalues,
only to lvalues/objects. C99 restrict is syntactically also a
qualifier, although semantically it sort-of bridges from the
so-qualified lvalue to the (pointer) rvalue stored therein.

The OP's technique is arguable -- with a C99 lib/headers it's
redundant, and with any other lib/headers you aren't guaranteed and in
practice won't get any checking that you matched the definition, and
if you don't IME the presence of the apparently-correct declaration
tends to confuse matters and impede diagnosis. But it will compile.

- formerly david.thompson1 || achar(64) || worldnet.att.net
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top