gnzlbg / ctest

Automatic testing of FFI bindings for Rust
https://docs.rs/ctest
Apache License 2.0
122 stars 29 forks source link

Use _Alignof instead of __alignof__ #75

Closed gnzlbg closed 5 years ago

gnzlbg commented 5 years ago

@sfackler can you test whether this PR resolves #74 for you ?

gnzlbg commented 5 years ago

AFAICT if the C / C++ compilers are new enough that they default to C11/C++11, then this should fix your issue. I don't know whether this is worth fixing for older compilers, but there are a couple of other things we could try to give a more accurate answer there.

An interesting trick is to do something like:

struct S {
    char c;
    type t; 
};
size_t alignment = (size_t)(&(((S*)0)->t));

Where we create a strut S, containing a char with alignment and size 1 at the front, and the type at offset 1. We then create a null pointer constant (0) and cast it to a S*, we use that to access the type field t, and create a pointer to that, and then cast that pointer to an integer. So if type has alignment 1, it will be right after the char, at offset one, and the memory address of it will be 0+1. So this returns the alignment of 1. If type has a higher alignment requirement, e.g. 4, it will be at a higher offset, e.g., 0 + 4, etc.

This is technically UB, in that we dereference a null pointer, but &*NULL is something that major C compilers do not miscompile.

gnzlbg commented 5 years ago

So I'm merging this since the last PR introduced this "regression": https://github.com/gnzlbg/ctest/pull/73/files#diff-b4aea3e418ccdb71239b96952d9cddb6L992

sfackler commented 5 years ago

Yep, looks like this fixed the issue - thanks!