6 ms·
They call it pre processor magic because it's difficult to maintain. Years ago, after writing an OR! Using C pre processor magic, I took a vow: Never again! Do
by Arelius 15y ago
They call it pre processor magic because it's difficult to maintain. Years ago, after writing an OR! Using C pre processor magic, I took a vow: Never again!
Do yourself a favor, either write clean, portable, clear and concise C code, or use a real pre-processor. The only time you should be using pre processor magic anyways is in a large project that's not a library anyways. So at that point it's pretty trivial to just use a proper pre-processor.
- cube13 15y agoPreprocessor magic is pretty much required if you want to write multiplatform code. I work on code for Solaris, Linux, and Windows, and makes life much easier to use #defines to standardize the OS calls.
- dpark 15y ago"#define somefunc _someplatformfunc" isn't exactly preprocessor magic. That's just basic preprocessor functionality. "Magic" is the stuff that no one else looking at the code understands, and it's complicated and generally fragile and frankly unnecessary.
- ori_b 15y agoOr you write platform specific code in it's own files, and link it in conditionally. port-linux.c port-win32.c port-solaris.c myprog.c and just compile/link port-$TARGET.c into your program. The code tends to be cleaner, and the platform knowledge is concentrated in one place.
- Arelius 15y agoIn my experience this is a much better approach. Most modern compilers can inline across linker boundaries anyways, so it's not a real performance issue either.
- LefterisJP 15y agoYes having platform specific code in its own header source and just #ifdef the includes provides much cleaner and nicer code
- ori_b 15y agoDon't even do that -- have one header that all the platform interfaces implement without ifdefs. Keep the conditional compilation in the makefiles, not in the source.
- cron 15y agoThe Linux kernel `container_of` and `offset_of` macros can be pretty handy when writing generic containers.
- Arelius 15y agoWhile those are both implemented as macros, I'd hardly call them "macro magic" at least not in the manner used by OP, or what I was talking about. Both of those are actually rather simple macros doing what seems like a mess with pointers. The difference is subtle, but most strongly expressed in that the complexity is innate to the problem, and does not require mucking much with what is entirely weird macro behavior.
- 16s 15y agoThere are lots of magic in C and C++ that most people are unaware of or told never to do. But, that magic is used often by older programmers. For example, this is perfectly valid C++ (no compiler warnings or errors even with -Wall and -Wextra) it's roots are in C: #include <iostream> #include <boost/integer.hpp> int main() { // Notice these signed types are going into unsigned types! boost::uint64_t i = -9151314442815602945; std::cout << i << std::endl; unsigned int j = -327681234; std::cout << j << std::endl; return 0; }