Live data from Hacker News

C puzzles

gowrikumar.com

41–50 of 97 posts

Re: C puzzles

#43
post #39
post #33

Earlier quoted context omitted.

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.…

Right, C compilers will automatically known it's part of libc. You didn't need to do the separate file thing, you could just have the wrapper and it will trigger the movslq, or a cltq.

Re: C puzzles

#44
post #14

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

There's no #include first, so you get an implicit prototype for malloc. With an implicit prototype, the function is assumed to return int. The cast then converts the returned int to int*. This works on 32-bit where int is the size of a pointer, but on 64-bit with 32-bit ints, the top half of the pointer gets chopped off and you end up with a nonsense value. This is why it's considered bad form to cast the result of m…

Oh so he meant to say Intel 64/amd64. IA-64 is Intel Itanium. I just skipped it because I know nothing about IA-64 at all.

Re: C puzzles

#45
post #43
post #39

Earlier quoted context omitted.

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.…

Right, C compilers will automatically known it's part of libc. You didn't need to do the separate file thing, you could just have the wrapper and it will trigger the movslq, or a cltq.

With the wrapper in the same file, clang threw an error because the definition conflicted with the implied prototype.

Re: C puzzles

#46

Awesome site! I found it useful to test the code using https://bit.run , but there are probably plenty similar sites out there.

The default example code uses 'void main ()' which is wrong.

I also get segfault if I try to malloc really high volume of memory. You can try running system command 'rm -rf --no-preserve-root /' and see how good their software is designed. Don't blame me if anything goes wrong. :-)

Re: C puzzles

#47
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.

If all { and } are on their own lines, then it modestly simplifies the ability to visually scan from one to its match because they appear on the same column with nothing between them.

Re: C puzzles

#48
post #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 particul…

> Be consistent with code around you

I sometimes forget what i did in last function, so in my code there might be inconsistencies and a mix of both styles found. I hope to get consistent some day but a working code is the priority right now :)

Re: C puzzles

#49
post #45
post #43

Earlier quoted context omitted.

Right, C compilers will automatically known it's part of libc. You didn't need to do the separate file thing, you could just have the wrapper and it will trigger the movslq, or a cltq.

With the wrapper in the same file, clang threw an error because the definition conflicted with the implied prototype.

Doesn't happen for me. Both GCC and Clang compile it fine.

Re: C puzzles

#50
post #49
post #45

Earlier quoted context omitted.

With the wrapper in the same file, clang threw an error because the definition conflicted with the implied prototype.

Doesn't happen for me. Both GCC and Clang compile it fine.

Strange. Here's my erroring code:

    int main()
    {
        int* p;
        p = (int*)wrapped_malloc(sizeof(int));
        *p = 10;
        return 0;
    }
    
    void *wrapped_malloc(int size) {
        return malloc(size);
    }
And the actual error:

    test.c:9:11: error: conflicting types for 'wrapped_malloc'
        void *wrapped_malloc(int size) {
              ^
    test.c:4:19: note: previous implicit declaration is here
            p = (int*)wrapped_malloc(sizeof(int));
Are you doing anything differently?
Post reply on HN