A dreadful thing

Saturday, October 4th, 2008 10:32
[personal profile] kpreid
some type *foo;
size_t count = ...;

...

foo = malloc(count * sizeof * foo);

(no subject)

Date: 2008-10-04 14:44 (UTC)
From: [identity profile] dougo.livejournal.com
Please tell me that doesn't compile... sizeof is an undeclared variable, right?

(no subject)

Date: 2008-10-04 15:14 (UTC)
From: [identity profile] kpreid.livejournal.com
No, sizeof is a unary prefix operator, and the parentheses are only required if the argument is a type.

(no subject)

Date: 2008-10-04 15:56 (UTC)
From: [identity profile] dougo.livejournal.com
But if it's followed by an asterisk, doesn't it parse as a variable? Or if it's a reserved word, shouldn't it just not parse at all?

(no subject)

Date: 2008-10-04 16:06 (UTC)
From: [identity profile] kpreid.livejournal.com
sizeof is a reserved word and so is always a prefix operator. Given that it's there, the next * is the prefix dereference operator. So it's identical to the normal ( count * sizeof ( * foo ) )

(no subject)

Date: 2008-10-04 16:29 (UTC)
From: [identity profile] dougo.livejournal.com
OH. Good lord. :(

Is it just a spacing thing?

Date: 2008-10-04 16:11 (UTC)
From: [identity profile] splogs.livejournal.com

The spacing is obviously dreadful; however, the result is what you'd expect, right? Given the following code, we can distinguish what happens in sizeof calls.


#include <stdlib.h>
#include <stdio.h>

int
main()
{
  char *foo;

  printf("type size=%u\n", sizeof *foo);
  printf("ptr  size=%u\n", sizeof foo);

  return 0;
}

Once run (on a 32-bit machine), we get the output indicated by the printf calls.

$ ./a.out 
type size=1
ptr  size=4

So, in the end, it's just a matter of knowing operators and precedence. If one does any C programming, this is always an important thing to pick up.

Another one...

Date: 2008-10-04 23:09 (UTC)
From: (Anonymous)

while (i --> 0) // "Goes to" operator
{
foo(i);
}

(no subject)

Date: 2008-10-04 23:33 (UTC)
From: (Anonymous)
This just goes to show that putting a space after the * if it dereferences a pointer is a bad habit. Keep them sticking to your variable names, folks!

(no subject)

Date: 2008-10-05 02:20 (UTC)
From: [identity profile] mattsnaps.livejournal.com
If I saw that line of code in a project I worked on, I'd assume it was a bug and talk to the developer who wrote it. If that dev told me it was not a bug, I'd ask him to add parentheses. If he didn't want to to that, well, then I'd kick him right in the fucking nuts.

Yet another one...

Date: 2008-10-05 12:57 (UTC)
From: (Anonymous)
int true = 1;
while (true) {
...
if (...) true = 0;
...
}

My favourite

Date: 2008-10-05 16:05 (UTC)
From: [identity profile] rgs26.livejournal.com
I especially like this one:
double x = x * 2;

Re: My favourite

Date: 2009-04-19 17:14 (UTC)
From: [identity profile] kpreid.livejournal.com
I just noticed that this is valid Haskell code, defining a function. As well as C code not defining a function.

Re: My favourite

Date: 2009-04-22 08:27 (UTC)
From: [identity profile] rgs26.livejournal.com
The C code exhibits undefined behaviour. If the stack garbage used as 'x' is a signaling NaN, that line can cause your program to crash...

Horrible

Date: 2008-10-07 05:28 (UTC)
From: (Anonymous)
It is one more example for the horrible syntax that C or C++ allow.

See also:

- C++ Pitfalls: http://www.horstmann.com/cpp/pitfalls.html
- C++ FQA lite: http://yosefk.com/c++fqa/
- C++?? : A Critique of C++ (3rd Ed.): http://burks.bton.ac.uk/burks/pcinfo/progdocs/cppcrit/