Live data from Hacker News

C puzzles

gowrikumar.com

31–40 of 97 posts

Re: C puzzles

#31

I really dislike his choice of coding style. Compare: int CountBits (unsigned int x ) { static unsigned int mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF } ; int i ; int shift ; /* Number of positions to shift to right*/ for ( i =0, shift =1; i > shift) & mask[i]); return x; } as opposed to: int countBits (unsigned int x) { static unsigned int mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x0…

I dislike your choice, too. So?

    int count_bits(uint32_t x)
    {
    	static const uint32_t mask[] = {
    		0x55555555,
    		0x33333333,
    		0x0f0f0f0f,
    		0x00ff00ff,
    		0x0000ffff
    	};
    	
    	for (int i = 0, shift = 1; i > shift) & mask[i]);
    	return x;
    }

Re: C puzzles

#32

I really dislike his choice of coding style. Compare: int CountBits (unsigned int x ) { static unsigned int mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF } ; int i ; int shift ; /* Number of positions to shift to right*/ for ( i =0, shift =1; i > shift) & mask[i]); return x; } as opposed to: int countBits (unsigned int x) { static unsigned int mask[] = { 0x55555555, 0x33333333, 0x0F0F0F0F, 0x0…

Really, are we going to argue about the One True Formatting style?

A 2 space indent is more compact. A 4 space indent is more readable for older people. Putting braces around blocks on their own lines highlights blocks. Putting braces inline is again more compact. Outdenting declarations highlights an important piece of information. Keeping them in line focuses on blocks. And so on.

None of these choices are particularly important. Being CONSISTENT does. This is his site, and his code. Adapt. If he comes to work with you, then he'll need to adapt to you.

Yes, it is a shock to see someone whose style is unfamiliar to you. Each of your choices has a reason behind it, and you may have thought through all of them. But it matters less than you think. Grow up and get over it. Be consistent with code around you.

Re: C puzzles

#33
post #28
post #27

Earlier quoted context omitted.

There is no cast that happens behind the scene, look at the generated assembly.

Do you mean that the cast in the code gets compiled out?

No. The int to int * truncation does not happen, the cast does not matter. What matters is the `int *p' which is 64-bit on 64-bit systems, so the compiler will just move the returned value in RAX into wherever p is, so no truncation happens, even without the cast. Look at the generated assembly, you'll see what I mean.

Re: C puzzles

#34
post #26

That IA-64 one is really puzzling, anyone know what the heck is happening?

Has nothing to do with includes, it has no error. The C compiler will automatically know its imported. He probably thinks that `int *` is 32-bit regardless.

It has everything to do with includes. Just think how implicit declarations are defined.

Re: C puzzles

#35
The last question:

> Write a C program which prints Hello World! without using a semicolon!!!

That seems daunting. At first.

Re: C puzzles

#36
post #34
post #26

Earlier quoted context omitted.

Has nothing to do with includes, it has no error. The C compiler will automatically know its imported. He probably thinks that `int *` is 32-bit regardless.

It has everything to do with includes. Just think how implicit declarations are defined.

Just think of the generated assembly.

Re: C puzzles

#38
post #22
post #12

Earlier quoted context omitted.

I prefer the one who takes a dedicated line for the `{`. It leaves me the ability to group together chunks of related functionality, whereas the latter method throws out that option instantly.

Huh??? Can you please elaborate on that? Because that makes no sense to me at all.

[deleted]

Re: C puzzles

#39
post #33
post #28

Earlier quoted context omitted.

Do you mean that the cast in the code gets compiled out?

No. The int to int * truncation does not happen, the cast does not matter. What matters is the `int *p' which is 64-bit on 64-bit systems, so the compiler will just move the returned value in RAX into wherever p is, so no truncation happens, even without the cast. Look at the generated assembly, you'll see what I mean.

Clang is too clever and gives malloc the correct implicit declaration even when you don't have an explicit prototype:

    test.c:10:12: warning: implicitly declaring library function 'malloc' with type 'void *(unsigned long)'
      [-Wimplicit-function-declaration]
I think that having a prototype mismatch with the actual declared function is undefined behavior, so this is a legal way to resolve it, but not every compiler will. Older compilers tended to treat malloc as just another function and wouldn't do this.

I was able to replicate the older behavior by wrapping malloc in my own function. In one file:

    int main()
    {
        int* p;
        p = (int*)wrapped_malloc(sizeof(int));
        *p = 10;
        return 0;
    }
    
And in another file:

    void *wrapped_malloc(int size) {
        return malloc(size);
    }
Compiling them into one program results in a crash. The relevant bit of assembly is:

    0000000100000f4f	movslq	%eax, %rdi
So it is indeed only extracting the lower 32 bits of the returned pointer.

The page looks pretty old (the IA-64 reference sure is dated, anyway) so I'd guess that it was referring to an older compiler that didn't have a special case for malloc like this.

Re: C puzzles

#40
post #35

The last question: > Write a C program which prints Hello World! without using a semicolon!!! That seems daunting. At first.

This could be fun to golf... smallest I've got is

    main(){if(puts("Hello World!")){}}
Post reply on HN