Hacker News new | past | comments | ask | show | jobs | submit login

> in fact you need to work quite hard to allocate a structure with a pointer that isn't at least 4 byte aligned (i386), or 8 byte aligned (x64).

Well, no, actually; it's:

  p = malloc(size+1)+1;
It's just quite implausible that you'd do that by accident.



Well no it isn't since malloc returns a void* and incrementing a void* is impossible for a compiler to figure out the offset that it needs to increment address for. For that operation to succeed/compile you need to cast the result of malloc first to p*. This means that the resulting alignment will still be correct.

The actual danger is in reinterpreting the pointers, or thereof some arbitrary chunk of memory, to a type that doesn't necessarily satisfy the alignment requirements for that given memory address.


gcc will compile this code and advance the pointer address by 1 byte. Yes, it's not standard conformant.

My point though is that this is unlikely to happen by accident. The code above is clearly constructed. It's more work to type it than the correct version. The code makes no sense at all. 1 byte is wasted and it's in general a bad idea to allocate unaligned pointers.

And when you for example provide your own allocator for nodes, you'll probably do it like this:

   Treenode treenode_pool[MAX_NODES];
or this:

   Treenode *treenode_pool = allocate(Treenode, node_count);
And the memory will be aligned properly. Even when you use a plain malloc (no type or alignment information given to the allocator) you will get memory that is at least pointer-aligned.


> gcc will compile this code and advance the pointer address by 1 byte. Yes, it's not standard conformant.

https://godbolt.org/z/cjoYvjxGq

    <source>: In function 'void foo(int)':
    <source>:4:28: warning: pointer of type 'void *' used in arithmetic [-Wpointer-arith]
        4 |     int * p = malloc(size) + 1;
          |               ~~~~~~~~~~~~~^~~
    <source>:4:28: error: invalid conversion from 'void*' to 'int*' [-fpermissive]
        4 |     int \* p = malloc(size) + 1;
          |               ~~~~~~~~~~~~~^~~
          |                            |
          |                            void\*
    Compiler returned: 1


first, yes it did accept the pointer arithmetic even though it issued a warning.

Second, the error about implicit conversion from void-pointer to typed-pointer is in C++ only -- not in C, where you won't even get a warning. The error happens because you didn't cast the void pointer to the target type and doesn't have to do anything with the fact that gcc _does_ let you (as a GCC extension) do arithmetic on void pointers.

If you remove the "+ 1" you'll still see the same error in C++. In C++, change the target pointer to a void pointer:

   void *ptr = malloc(42) + 1;
or, alternatively, cast the RHS expression properly (doesn't matter with "+ 1" or without)

   int *ptr = (int *) (malloc(42) + 1);
and the error will go away.


I don't think there's a need to explain to me how pointers work, or what to do to make this error/warning go away, since it should be pretty obvious from my response that this is something I know very well.

I was only disputing the claim that ending up with the unaligned ptr is not trivial for given line of code by providing explanation, and counter-example, why this is not possible. At least not in C++ because that's the language I had in mind.

What you're saying is that it's possible to do void pointer arithmetic in C by using the GNU extension - fine, I can't disagree with that.


You corrected me and I corrected you. No need to take personal offense. I don't care what you know -- I obviously took the compiler output that you presented above as a refutal to what I said earlier, and I pointed out why it's not a valid refutal.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: