Funny C Rules (And Low-Level Languages in general)

Discuss programming topics for the various GPL'd game engine sources.
jitspoe
Posts: 217
Joined: Mon Jan 17, 2005 5:27 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by jitspoe »

I generally return true on success for most functions, unless they can return more than 2 values. The compare functions return 0 for "true" or "equal" because they can return both positive and negative values, which matters when used for sorting. To reduce confusion, I've made my own functions for simple equality checks, like Q_streq(), so you don't have confusing code like "if (!strcmp(...".
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

ericw wrote:Yeah the
dest->foo = src->foo;
VectorCopy(src->pos, dest->pos);
thing is awful. Using "const" liberally could detect mixing up the order of VectorCopy, but usually in Quake both source and dest are mutable.

IMO the 0=success, 1=failure, or -1=less, 0=same, 1=greater stuff is horrible legacy style, but often you have to have no choice because you're using API's that use that. The right way is C++11's "enum class" which don't implicitly convert to int.
Hmm. I'm not sure. Imagine every function having their own set of unique enums. Enums are almost never complete because they seek to represent something larger compressed to a single byte or 4/8 bytes.

At least with a numeric function I only have to ask, ok what does this return on success/failure and there are only 2-3 possibilities. A decent function will return a enum --- boolean!
Last edited by Baker on Sun Mar 01, 2015 3:11 am, edited 1 time in total.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Funny C Rules (And Low-Level Languages in general)

Post by Spike »

0 for sucess makes sense in that you only have one success code, and multiple reasons for failure.
the alternative is the unix way, where <0 are errors, and >=0 are success codes. which is fine until you have 32bit+ results.
really its the difiference between a boolean and an (oob)enum. if the return value is defined as a bool of some kind, then its true for success. otherwise it should be 0 for success (as opposed to false).
and if its HRESULTS, use the FAILED or SUCCEEDED macros to provide the appropriate comparisons (note that these are consistant with the unix way).

VectorCopy is absurd. fix it BEFORE your engine becomes a sprawling monstrosity...
mankrip
Posts: 924
Joined: Fri Jul 04, 2008 3:02 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by mankrip »

My interpolation macros uses (previous_src, dest, next_src), because that's what makes more sense for me.

Also, trying to guess the order of any functions is bad. I always take a look at the function declaration if I don't know/remember the order.

And imo, error codes are also bad. Errors should be treated internally, instead of hoping that the functions that called the functions that generated the errors will take care of them.
Btw, this is why I dislike the conventional return values used by stuff like strcmp. When using strcmp, the coder is essentially asking "does those strings match?", and a no is a valid answer for such a question, so in cases like this it makes no sense to assign the return values as if they were error codes.
To me, a "no" doesn't mean that the comparison performed by strcmp failed. A real failure would be if strcmp couldn't determine whether does the strings match or not.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

mankrip wrote:When using strcmp, the coder is essentially asking "does those strings match?", and a no is a valid answer for such a question, so in cases like this it makes no sense to assign the return values as if they were error codes.
strcmp and memcmp's -1, 0, 1 return values are great for sorting.

An example is FitzQuake's cvar list. Your own engine feeds (sorting by distance) qsort --- which requires a comparison function be supplied, what is essentially memcmp (although I think you slightly wrap it).

In C there is an isdigit macro. I guess an oversight in C is not supplying a "do strings match macro" like #define strmatch(a, b) (strcmp(a,b) == 0) because everyone rolls their own or whatever a quality name for it would be.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
jitspoe
Posts: 217
Joined: Mon Jan 17, 2005 5:27 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by jitspoe »

I guess the parameter order thing is all a matter of perspective. I always thought it made sense reading left to right, like with VectorCopy(A, B); I'm starting with A, and copying it to B.

Consts and better parameter names (like VectorCopy(in, out)) can help with this confusion.

It wasn't until I read some posts here with "A = B;" that it even crossed my mind that it could make sense for the destination to be on the left. I always thought the leftmost parameter being the output was necessary for functions like sprintf() where the parameters were variable, so you couldn't have the output parameter be at the end, and some other functions just followed that to try to be consistent, not because it was intuitive.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

I had never consciously thought about A = B either, which is a winner. That provides some extra clarity (for what I always believed).

I had become accustomed to memcpy and strcpy, therefore VectorCopy messed with my head. Generally, when I write functions, any function that alters something I tend to have it as the first parameter (the operand).
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Funny C Rules (And Low-Level Languages in general)

Post by Spike »

mathematically, assignments commonly store to the righthand side. even quake's opcodes store to the right (yup, qcc interprets assignments the other way around from other 2-argument instructions).
really, consistancy is important.
even libc is inconsistant:
fputs(source, dest);
fprintf(dest, source);
personally I favour the object being updated as the first argument, because with stuff like fprintf, its easier to be consistant that way.
strlcpy(dest, source, destpart2); is annoying too.
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

Not really on-topic but ...I switched from Courier to the Liberation Mono font (which is fixed width). I get 15% more vertical lines. I can't tell any difference other than seeing more. I think the difference is mainly overhang/descent whatever you like to call what lowercase g, y, j do.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

Spike wrote: strlcpy(dest, source, destpart2)
I macro away strlcpy and snprintf to conform to strlcpy (dst, src, sizeof(dst)) and snprintf(dst, sizeof(dst), ...)

Mostly because I freakout that I might forget one of those parameters or put them in the wrong order.

I also occasionally use a macro that does a compile-time assert that screams if sizeof(dst) is sizeof(void *) to ensure that no instances are accidentally using a sizeof operation on a pointer.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
dimman
Posts: 7
Joined: Wed Jan 29, 2014 1:58 pm

Re: Funny C Rules (And Low-Level Languages in general)

Post by dimman »

A couple of notes:
12) Variables declared static or global variables have static storage duration and are initialized to zero
13) Due note that you cannot do sizeof int for instance, or any type, you do need parenthesis for those: sizeof(int)
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

dimman wrote:13) Due note that you cannot do sizeof int for instance, or any type, you do need parenthesis for those: sizeof(int)
Very interesting. I had to try that out.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

int y = 5;

These are are disallowed:
int x = y++5; // No spaces, so the C parser isn't being space agnostic or figuring out this only makes sense if it is y + (+5)
int x = y--5; // No spaces
But these are ok
int x = y*-5; // No spaces
int x = y+-5; // No spaces
int x = y- -5; // Space between the minus signs
int x = y+ +5; // Space between the plus signs
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

We think of comments as being ignored. This isn't actually true.

They are interpreted as whitespace.

int x/*hello*/y = 5; // Error. If the comments were ignored, this line would be int xy=5;
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Baker
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Re: Funny C Rules (And Low-Level Languages in general)

Post by Baker »

The * for a pointer is often tacked on to the name.

Code: Select all

const char *mystring;
But the * isn't part of the name.

static unsigned int * WINAPI myfunction (void); // Compiles. Notce placement to the left of WINAPI (the calling convention specifier)

static unsigned int WINAPI *myfunction (void); // Fails to compile. Can't have as part of the name.
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
Post Reply