Some problems with C code

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
mystran

Re:Some problems with C code

Post by mystran »

The only thing I'd like to add is that I believe it is a bit safer to assume that "sizeof(unsigned long) == sizeof(void*)" than to assume that "sizeof(int) == sizeof(void*)". Both hold on many architectures, but the first one holds a bit more often, especially on 64-bit archs. That said, when the code can't be portable anyway, who cares?
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re:Some problems with C code

Post by Brendan »

Hi,
mystran wrote: The only thing I'd like to add is that I believe it is a bit safer to assume that "sizeof(unsigned long) == sizeof(void*)" than to assume that "sizeof(int) == sizeof(void*)". Both hold on many architectures, but the first one holds a bit more often, especially on 64-bit archs. That said, when the code can't be portable anyway, who cares?
To assist with C's lack of portability, I refuse to use it's default data types. Instead I do something like:

Code: Select all

#define u8 unsigned char
#define s8 signed char
#define u16 unsigned short
#define s16 signed short
#define u32 unsigned int
#define s32 signed int
#define u64 unsigned long long
#define s64 signed long long
From then on I'd use the defines only. That way it's easier to port the C code to other C compilers, it's less typing and there's no guesswork...


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some problems with C code

Post by Solar »

You might want to look into the C99 header <stdint.h>, which defines, among others, types like uint32_t. In the very least, even if you don't use C99, you might want to copy the naming conventions, as it will make your code look more "familiar" to C99 vets.
Every good solution is obvious once you've found it.
Dreamsmith

Re:Some problems with C code

Post by Dreamsmith »

Bleh... I've never liked ANSI's stream of xxx_t defines, or Hungarian notation in general (if you're looking for rapists of the C language, may I suggest an aesthetic review of the X3J11 committee's work). uint16 would have been just a clear, more concise, and easier to type to boot. For that matter, enough people use u16, u32, s16, s32, etc., that this is not going to confuse anyone. However, you can make your porting job easier by using <stdint.>, and alter those defines:

Code: Select all

#define u16 uint16_t
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:Some problems with C code

Post by Candy »

May I suggest replacing those #defines with typedefs? they only convert the types containing those names, so you don't get really weird variable names with code like:

Code: Select all

int stu8;
During debugging, it'd be called stuint8_t, which is really not productive...
Dreamsmith

Re:Some problems with C code

Post by Dreamsmith »

Um, no. #defines work on entire words, not substrings.

#define abc def

int abcd;

The define will not have any effect on the name of the variable abcd.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some problems with C code

Post by Solar »

It's a matter of chosing the right tool for the job. Typename definitions should be done by typedef, and user-defined types should end in _t. You might not like it, but those are 'them rules.

And while I loathe hungarian notation myself, I very much prefer being able to distinguish a typename (uint32_t) from a potential variable name (u32) at a glance.

But it's all a matter of taste, and as such, you are inclined to your own opinion. ;)
Every good solution is obvious once you've found it.
Dreamsmith

Re:Some problems with C code

Post by Dreamsmith »

Solar wrote:And while I loathe hungarian notation myself, I very much prefer being able to distinguish a typename (uint32_t) from a potential variable name (u32) at a glance.
That is a nice feature, but there are less cumbersome and easier to read alternatives. Personally, I use the convention of always naming classes and types starting with a capital, and never naming functions or variables that way, thus when I see "Device" or "Color" I know that's a type, whereas "device" or "color" is a variable reference.

To each his (or her) own...
Schol-R-LEA

Re:Some problems with C code

Post by Schol-R-LEA »

The problem with that is that there are hundreds of existing C and C++ programs that don't follw that convention. The standard library convention at least is internally consistent, and unlikely to conflict with existing code.
Dreamsmith

Re:Some problems with C code

Post by Dreamsmith »

If the standard C types were char_t, int_t, double_t, etc., I might consider the internal consistency of the standard C library in this regard a significant fact. However, since the convention followed by the standard C library is already inconsistent with the language itself, therefore dooming one to inconsistency in any case, I'm not terribly impressed by the virtue of being consistent with the standard C library.

There is virtue in consistency, which is why I follow the convention I use consistently. I just don't see any good reason to use the same convention the standard C library uses -- not when they've gone out of their way to select an ugly and cumbersome convention.

What was it Kerry said? Being consistent isn't a virtue if you're consistently wrong? Or something like that... ;)
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Re:Some problems with C code

Post by Solar »

The thing is simply that the language standard committees have to deal with "prior art", and hence have to minimize the impact of subsequent decisions on existing code.

One example. The C++ standard library does not contain a hash table. This lack was felt by many a library vendor, and they added (implementation defined) extensions like hash_table, hash_map etc.

Now, the C++ committee wants to extend the standard library to contain hash tables. The problem is, how to do it without breaking the code of all those people that already used hash_table, hash_map etc., and would like to make the transition to the new standard hash tables piecemeal? You need a name for the new hash tables that is unlikely to collide with existing type names.

So they chose something like unordered_map or something like that. Ugly, yes. It gives you the creeps. But it is the lesser of two evils.

Same with many things in the C standard, like the _t notation. It's not great, but it's the best we have.
Every good solution is obvious once you've found it.
Dreamsmith

Re:Some problems with C code

Post by Dreamsmith »

Solar wrote:The thing is simply that the language standard committees have to deal with "prior art", and hence have to minimize the impact of subsequent decisions on existing code.
Indeed, and for that reason, they needed to choose something so non-standard (in the sense of not commonly used by people programming in the industry at the time [myself included]) that they wouldn't step on anyone's toes.
Solar wrote:Same with many things in the C standard, like the _t notation. It's not great, but it's the best we have.
On the contrary. It was the best solution for the particular problem they needed to solve. It is far from the best solution for most people's uses. I don't object to the fact that the standard needed it and used it. What I object to is the silly notion that anyone who isn't part of X3J11 or whatever committee has taken over the process these days should somehow feel constrained to adopt the same solution when confronted with a different set of issues.

You aren't working on code to be included in the next C standard library. You're working on code that, hopefully, you want to remain compatible with Standard C, not only now but into the future if you want to avoid headaches down the road. Therefore, you should go out of your way to avoid naming your own types ending in "_t". As long as you avoid doing so, you can rest assured that your type names will not collide with future expansions of types under Standard C -- treat anything ending with "_t" as reserved for use by the standards committees, and you'll have no problem.

OTOH, if you start naming your own types ending with "_t", you set yourself up for name collisions as soon as they next standard is published. Code that intends to be portable and compatible with future standards should avoid as much as posssible adopting such conventions. Using a different convention gives the added benefit of making it easy to distinguish user-defined types from standard-library-defined types. And if you choose well, you'll probably have more readable code that was easier to type as well.
Post Reply