C style question

E

Edward Rutherford

Hello

I have been looking at some code which "for faster compilation" has ad hoc
declarations of some standard functions instead of including standard
headers.

E.g.

typedef unsigned int long size_t;
extern void* malloc(size_t);

This feels to me like it's bad style, but I can't quite put my finger on
anything specific that's wrong with it.

What do people think about this approach?

- Ed
 
I

Ian Collins

Hello

I have been looking at some code which "for faster compilation" has ad hoc
declarations of some standard functions instead of including standard
headers.

E.g.

typedef unsigned int long size_t;
extern void* malloc(size_t);

This feels to me like it's bad style, but I can't quite put my finger on
anything specific that's wrong with it.

What do people think about this approach?

It's terrible style and renders the code non-conforming.

It is not uncommon for system headers to use different types or even
calling conventions for different environments (32/64 bit for example).
Once you start adding your own declarations, you may well end up with
code that at best won't link, at worst links but does weird things. A
quick look at you systems headers should show you what I mean
 
K

Keith Thompson

That's an odd way of declaring it. "unsigned int long" is legal, but
"unsigned long int" (or just "unsigned long") is much more common.
It's terrible style
Yes.

and renders the code non-conforming.

No. In fact, the standard specifically permits this. C99 7.1.4p2:

Provided that a library function can be declared without
reference to any type defined in a header, it is also permissible
to declare the function and use it without including its
associated header.

You can't declare fopen() this way, for example, because you need
<stdio.h> to get the correct declaration for type FILE.

Hmm. I suppose size_t is "type defined in a header", but as long
as the implementation actually does typedefs size_t as unsigned long
int, there shouldn't be any problem declaring it that way yourself.
Strictly speaking, the standard doesn't permit it, but I think that
only a deliberately perverse implementation would break it.
It is not uncommon for system headers to use different types or even
calling conventions for different environments (32/64 bit for example).
Once you start adding your own declarations, you may well end up with
code that at best won't link, at worst links but does weird things. A
quick look at you systems headers should show you what I mean

You're guaranteed to be able to do this:
void *(*p)(size_t);
p = malloc;
and the implementation isn't permitted to play any tricks that would
break that.

Another issue, though, is that some standard function declarations
changed between C90 and C99 (the addition of "restrict" keywords,
for example). These changes have no effect on correct code,
but you could run into trouble if you try to mimic the standard
declarations yourself.

The idea, apparently, is to expend considerable manual effort
writing these declarations to reduce effort for the compiler.
Apart from being error-prone, IMHO this ignores the whole point of
what computers are for.
 
A

Anders Wegge Keller

Edward Rutherford said:
I have been looking at some code which "for faster compilation" has
ad hoc declarations of some standard functions instead of including
standard headers.

Unless the system headers reside on a *very* slow storage medium,
like a NFS filesystem with locking issues, and then the problem should
be fixed elsewhere, that sound like a premature optimization to me.
typedef unsigned int long size_t;
extern void* malloc(size_t);
This feels to me like it's bad style, but I can't quite put my
finger on anything specific that's wrong with it.

If portability is not an issue, it may be brought to work. But I'll
guess that the time spent debugging subtle bugs caused by interaction
between code "optimized" in this way, and conformant code will
probably exceed the time saved in the first place.
What do people think about this approach?

I would rewrite the code to include the proper header files.
 
I

Ian Collins

That's an odd way of declaring it. "unsigned int long" is legal, but
"unsigned long int" (or just "unsigned long") is much more common.


No. In fact, the standard specifically permits this. C99 7.1.4p2:

Provided that a library function can be declared without
reference to any type defined in a header, it is also permissible
to declare the function and use it without including its
associated header.

You can't declare fopen() this way, for example, because you need
<stdio.h> to get the correct declaration for type FILE.

Hmm. I suppose size_t is "type defined in a header", but as long
as the implementation actually does typedefs size_t as unsigned long
int, there shouldn't be any problem declaring it that way yourself.
Strictly speaking, the standard doesn't permit it, but I think that
only a deliberately perverse implementation would break it.

That was my point, if you declare a typedef like size_t in a different
way from the system headers, all bets are off.
You're guaranteed to be able to do this:
void *(*p)(size_t);
p = malloc;
and the implementation isn't permitted to play any tricks that would
break that.

That's assuming you gave your malloc the correct return type. If you
had declared malloc as

int malloc(size_t);

Your code would link, but not behave as you had intended....
 
S

Seebs

I would rewrite the code to include the proper header files.

Seconded.

Lemme tell you why.

I hate PINE. I hate it with a fiery, burning, and unending passion. Because,
you see, PINE (at least in the past) used to do this garbage. They REFUSED to
use standard headers. Instead, for each target, they'd carefully create what
they thought were probably the right declarations to use.

They were wrong.

This meant that, as soon as you tried PINE on a big-endian machine with a
64-bit filesystem, EVERYTHING blew up, data was lost, files were destroyed.

BECAUSE THEY WERE WRONG.

Note that their explanation was actually worse; apparently, there had once
existed a machine on which (they claim) the standard headers mis-declared
things, so they concluded it was "safer" to provide their own declarations.

There are two problems with this:
1. No one looking at that code would ever conclude that, had the author
of that code found a "bug" in a compiler, there was a legitimate basis for
thinking that the compiler had actually been at fault.
2. Breaking dozens of systems on the grounds that you once found one which
was broken is not a good trade-off.

Never do this.

To put this in perspective: I maintain a utility which works by intercepting
calls to the standard library and operating system and replacing them with
duplicates. That is to say, if you are running with this utility, and
you write:
FILE *fp = fopen(...);
your code will call *my* fopen, not the host environment one.

I use the prototype declarations from the standard headers. (It's fussier,
because I provide *definitions* of my own, which merely match signatures, but
I still let <stdio.h> provide the initial declaration of fopen().)

So, even if you really ARE writing your own versions of these functions,
it is still suicidally stupid not to use the standard headers for them.

Yes, in theory you might be able to do it correctly. You also might not.

-s
 
J

Jorgen Grahn

....



If portability is not an issue, it may be brought to work. But I'll
guess that the time spent debugging subtle bugs caused by interaction
between code "optimized" in this way, and conformant code will
probably exceed the time saved in the first place.

Even if no such bugs appeared, I'd waste time *worrying* that this
weirdness caused the problem, for every real bug in the code.

/Jorgen
 
E

Eric Sosman

Hello

I have been looking at some code which "for faster compilation" has ad hoc
declarations of some standard functions instead of including standard
headers.

E.g.

typedef unsigned int long size_t;
extern void* malloc(size_t);

This feels to me like it's bad style, but I can't quite put my finger on
anything specific that's wrong with it.

What do people think about this approach?

Bleaggh! (That's technical jargon with a meaning related to
"Yuck!" and "Puke!" and "Retch!" and "Ug-ugh-ugggh-BARF!")

It imperils the programmer's immortal soul by disobeying the
Fourth Commandment (http://www.lysator.liu.se/c/ten-commandments.html),
not even subtly or slightly but directly, openly, and flagrantly.

It's also wrong, R-O-N-G, wrong on any system where `size_t' is
not an alias for `unsigned long', but is some other type -- like
`unsigned int' or `unsigned long long' or `__builtin_size_t_type'.
I'm given to understand that Win64 is one such system, and there
are quite likely others.

Not only that, but it's a fornicating stupid thing to do.

Don't Do That.
 
T

Tim Rentsch

Ian Collins said:
It's terrible style and renders the code non-conforming.

You may not like the style, but technically speaking it is
conforming. Section 4, p 7.
 
T

Tim Rentsch

Eric Sosman said:
Bleaggh! (That's technical jargon with a meaning related to
"Yuck!" and "Puke!" and "Retch!" and "Ug-ugh-ugggh-BARF!")

It imperils the programmer's immortal soul by disobeying the
Fourth Commandment (http://www.lysator.liu.se/c/ten-commandments.html),
not even subtly or slightly but directly, openly, and flagrantly.

It's also wrong, R-O-N-G, wrong on any system where `size_t' is
not an alias for `unsigned long', but is some other type -- like
`unsigned int' or `unsigned long long' or `__builtin_size_t_type'.
I'm given to understand that Win64 is one such system, and there
are quite likely others.

Not only that, but it's a fornicating stupid thing to do.

Don't Do That.

Don't hold back, Eric - tell us what you really think. :)
 

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,776
Messages
2,569,603
Members
45,196
Latest member
TopCryptoTxSoftwares2024

Latest Threads

Top