I'd really like a portable way to use alignof and alignas. This seems impossible, especially on old compilers, but I still think libecb might still try to help in some cases. I don't know the final solution of what could be done, so here I'm trying to collect information about what compilers support what features, and how you can test them without a configure system. I'll take alignof and alignas separately. These are mostly symmetric, but have differences.
== alignof == The C++11 alignof keyword queries the required alignment of a type. 1. The alignof keyword is available in C++11, C++ in starting from gcc 4.8, C++ in clang if __has_feature(cxx_alignas), but not yet in any version of the MS compiler. 2. The _Alignof keyword, and the macro alignof in <stdalign.h>, is available in C11, and I don't know the compiler versions. 3. The GCC __alignof__ keyword is available starting from ancient times (before gcc 3). 4. The MS compiler has an __alignof keyword. 5. The std::alignment_of template in <type_traits> would be a suitable replacement to alignof, but it's probably only available in C++11 compilers that have alignof anyway. 6. Boost has an implementation of the alignment_of in the TypeTraits library for some compilers, unknown header and namespace, which might give some hints if only you could untangle the source code. 7. The boost config module has some macros like BOOST_NO_CXX11_ALIGNAS that try to tell whether compilers have C++11 alignas, but it's hard to read the boost source code to find out how this works, and it's sometimes not precise, so it's useful only as a starting point. == alignas == The alignas specifier is more complicated because it can syntactically appear in multiple places in the code (qualifying a struct or an object declaration), and only some of these could be possible on certain compilers, and also because it can take both a type or a value as its parameter. Let me talk about these separately now. 1. The alignas keyword is available in C++11, C++ in starting from gcc 4.8, unknown versions of clang, but not yet in any version of the MS compiler. 2. The _Alignas keyword, and the macro alignas in <stdalign.h>, is available in C11, and I don't know the compiler versions. 3. There's a gcc-specific attribute __attribute__((aligned())) starting from ancient times (before gcc 3), and can be applied to both structure and variable definitions. This takes only an alignment number parameter, not a type. 4. There's an MS complier attribute __declspec(align()). I think this doesn't quite support the full semantics of alignof, but can still help in some cases. The MSDN documentation at "https://msdn.microsoft.com/en-us/library/83ythb65.aspx" promises a lot but is a bit suspicious and haven't been updated for a while. In any case, the MS compiler seems to have some strange ideas about alignment, in particular, it sometimes doesn't align objects on the stack, which could be why they don't want to add the alignas keyword. Still, this attribute may help for at least global variables. 5. The std::aligned_storage template class lets you create overaligned types in some special cases and with ugly syntax. However, it is probably available only in C++11 compilers that have alignas anyway, so it won't help much. 6. Boost has an implementation of aligned_storage somewhere in the TypeTraits module, which could give some hints. 8. You can sometimes use a union with a highly aligned type to create aligned storage, but this only helps if you have a type that's highly aligned in first place, so 64-byte alignment this way is impossible except in the latest systems. The syntax of where you can place these in a declaration is picky, and differ for these. For a struct definition, put alignas(32) or __attribute__((aligned(32))) or __declspec(align(32)) between the struct keyword and the name of the newly defined structure type. For a variable (member) definition, put alignas(32) or __attribute((aligned(32))) or __declspec(align(32)) at the very beginning of the declaration. Placing them like these is at least accepted without a warning on some compilers, but it's hard to be sure it actually set alignment. == other stuff == Sometimes I'd like an aligned_alloc function (as in C11). Most C libraries, even the oldest ones, seem to have something like this, but with lots of differences in the interface. Boost has an implementation which seems to work, but I think it doesn't always do the optimal thing. This, however, probably does not belong to libecb. Slightly related is reading and writing unaligned integers in the memory (and possibly floats too). Boost now has a library that I can use for this (called Endian), which supports unaligned integers of all sizes and endiannesses, with a C++ interface. This has at least some platform-specific optimizations for endianness swaps. I don't know whether it can handle unaligned accesses efficiently, and that might even be impossible on x86 systems, where some cpu instructions allow unaligned access, some don't, some depend on some modes or states or cpu types, and compilers don't seem to have an interface to do unaligned access, even though I think they should. I've used this library to read a misaligned int64_t recently, but that didn't require any sort of performance. Anyway, if you can figure out how to handle this properly, some functions for this could still be useful for libecb. -- Ambrus _______________________________________________ libev mailing list libev@lists.schmorp.de http://lists.schmorp.de/mailman/listinfo/libev