Re: FXDir + strict aliasing?
Jeroen van der Zijp <[email protected]>
| Newsgroups | gmane.comp.lib.fox-toolkit.user |
|---|---|
| Organization | FOX Toolkit |
| Message-ID | <[email protected]> |
On Sat, 22 Oct 2022 09:17:14 -0500 Sander Jansen <[email protected]> wrote: > How do you intent on fixing strict aliasing warnings in FXDir? > > Something like this would probably optimize away: > > > inline static void space_set_handle(FXuval * space, DIR * v){ > memcpy(space + __builtin_offsetof(SPACE, handle), &v, sizeof(v)); > } > > inline static void space_set_dp(FXuval * space, struct dirent* v){ > memcpy(space + __builtin_offsetof(SPACE, dp), &v, sizeof(v)); > } > > inline static SPACE space_cast(const FXuval * space) { > SPACE dst; > memcpy(&dst, space, sizeof(SPACE)); > return dst; > } > // Construct directory enumerator > FXDir::FXDir(){ > space_set_handle(space, nullptr); > } > // Open directory to path, return true if ok. > FXbool FXDir::open(const FXString& path){ > .... > DIR * handle = opendir(path.text()); > if (handle != nullptr) { > space_set_handle(space, handle); > return true; > } > > .... > // Returns true if the directory is open > FXbool FXDir::isOpen() const { > return space_cast(space).handle != nullptr; > } OK, After Googling it (with Bing!), I found this stackoverflow suggestion: https://stackoverflow.com/questions/2958633/gcc-strict-aliasing-and-horror-stories Sadly, that does not work (anymore). Apart from the fact that typeof() is not [officially] a C++ thing. But, it did set me on the path of a possible solution. This is just an idea, somebody may be able to improve on it before I really implement it everywhere: template <typename FROMTYPE,typename TOTYPE> union UNI { FROMTYPE src[1]; TOTYPE dst[1]; }; template <typename FROMTYPE,typename TOTYPE> static inline TOTYPE* alias_cast(FROMTYPE* ptr){ return reinterpret_cast<UNI<FROMTYPE,TOTYPE>*>(ptr)->dst; } template <typename FROMTYPE,typename TOTYPE> static inline const TOTYPE* alias_cast(const FROMTYPE* ptr){ return reinterpret_cast<const UNI<FROMTYPE,TOTYPE>*>(ptr)->dst; } Then: // Internal guts of FXDir: struct SPACE { DIR* handle; struct dirent* dp; }; // Access member of SPACE alias_cast<FXuval,SPACE>(space)->handle=nullptr; Rationale of this stuff: (1) Public header files are hiding details for internal details which are operating system dependent. (2) Obviate need to include platform dependent header files in user-code. (3) And yet no slower than if these data were declared as member variables. (4) We declere FXuval as its a type which has natural alignment on most operation systems; just in case member variables in the interior structure have particular alignment requirements. I'd love it if someone has an even better solution! --- The GCC option -fstrict-aliasing encourages optimizations by assuming that variables of different types are not aliased, i.e. will not occupy overlapping memory. The "horror stories" in stackoverflow seem to indicate that GCC may be a bit aggressive with these assumptions. So we have either the choice of foregoing the optimizations or sticking to the "officially sanctioned" type-punning via unions. The code above does this... -- JVZ