happymonster
|
|
« on: April 08, 2015, 01:05:08 AM » |
|
What are your favourite #defines that you use in C/C++ for your projects? I always seem to use MIN, MID and MAX defines in every project. What about you?
|
|
|
Logged
|
|
|
|
Schrompf
|
|
« Reply #1 on: April 08, 2015, 02:46:45 AM » |
|
#define NOMINMAX #include <windows.h>
probably. I mostly don't use it at all, except for #if IS_THIS_WINDOWS_OR_WHAT. min() and max() are already there in the std namespace, so why bother?
|
|
|
Logged
|
Snake World, multiplayer worm eats stuff and grows DevLog
|
|
|
oahda
|
|
« Reply #2 on: April 08, 2015, 03:20:43 AM » |
|
What are your favourite #defines that you use in C/C++ for your projects? I always seem to use MIN, MID and MAX defines in every project. What about you? I use std::min and std::max. Didn't know there was a mid, tho. I wrote my own between(). I don't use any macros besides those used for AngelScript, and I'll probably have to write some of my own so that I can bake AS properly into my lib w/o exposing it in the headers like I'm doing now, so that games using the library don't have to include AS too.
|
|
|
Logged
|
|
|
|
rcb
TIGBaby
|
|
« Reply #3 on: April 08, 2015, 03:58:44 AM » |
|
I think I missed that class when the proper way of defining interdependent classes was taught. So I end up including everything, everywhere. To avoid redefining stuff that gets included more than once, I do, in every .hpp file:
#ifndef FILENAME_WITHOUT_EXTENSION #define FILENAME_WITHOUT_EXTENSION
//code goes here
#endif
I never used MIN MAX or stuff like that; I prefer to set limits using argc / argv and some wrapper scripts. That way I can change limits without recompiling.
About #include <windows.h>, if I ever type that and it is not a joke, please shoot me in the head.
|
|
|
Logged
|
|
|
|
Average Software
|
|
« Reply #4 on: April 08, 2015, 04:37:50 AM » |
|
#define NOMINMAX #include <windows.h>
Oooh, I wish I'd known about NOMINMAX. That's interesting. #define DECLARE_ENUM_IO(Enum, ...) \ namespace EnumIO \ { \ template <> \ struct Traits<Enum> \ { \ static_assert(EnumRange::HasRange<Enum>::value, "Enum IO requires a defined range"); \ \ Traits() = delete; \ \ static \ constexpr std::array<const char*, EnumRange::Range<Enum>::forward().size()> strings() noexcept; \ }; \ } \ \ constexpr std::array<const char*, EnumRange::Range<Enum>::forward().size()> EnumIO::Traits<Enum>::strings() noexcept \ { \ return {{__VA_ARGS__}}; \ } #define DECLARE_ENUM_RANGE(Enum, ...) \ namespace EnumRange \ { \ template <> \ struct Range<Enum> \ { \ Range() = delete; \ \ static \ constexpr std::array<Enum, Internal::val_count(__VA_ARGS__)> forward() noexcept; \ }; \ } \ \ constexpr std::array<Enum, EnumRange::Internal::val_count(__VA_ARGS__)> EnumRange::Range<Enum>::forward() noexcept \ { \ return {{__VA_ARGS__}}; \ }
I'm rather partial to these. They're part of my system for allowing Ada style iteration and I/O of enum types.
|
|
|
Logged
|
What would John Carmack do?
|
|
|
oahda
|
|
« Reply #5 on: April 08, 2015, 05:56:15 AM » |
|
To avoid redefining stuff that gets included more than once, I do, in every .hpp file:
#ifndef FILENAME_WITHOUT_EXTENSION #define FILENAME_WITHOUT_EXTENSION
//code goes here
#endif
Everyone does that. It's called a header guard.
|
|
|
Logged
|
|
|
|
nickgravelyn
Guest
|
|
« Reply #6 on: April 08, 2015, 08:10:18 AM » |
|
To avoid redefining stuff that gets included more than once, I do, in every .hpp file:
#ifndef FILENAME_WITHOUT_EXTENSION #define FILENAME_WITHOUT_EXTENSION
//code goes here
#endif
Everyone does that. It's called a header guard. With a lot of modern compilers you can just use #pragma once. I know it works in Visual Studio (at least 2012 and newere, but I'm pretty sure even 2010 supports it) as well as Xcode (for some number of recent versions). I use #pragma once because It's just so much nicer and cleaner than header guards. I have a little macro for getting the size of a fixed length array: #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof(0[arr]))
int foo[5]; ARRAY_SIZE(foo) == 5
I believe some compilers have an arraysize() pseudo-function but not all that I've used. And I know there are better implementations of an array size macro that are more robust to stupid input and things, but for simple fixed size arrays like this the macro has served me well.
|
|
|
Logged
|
|
|
|
RandyGaul
|
|
« Reply #7 on: April 08, 2015, 09:28:34 AM » |
|
Definitely this one: OFFSET_OF( data, member ) ((int)(&((data*)0)->member))
|
|
|
Logged
|
|
|
|
Columbo
|
|
« Reply #8 on: April 08, 2015, 10:09:58 AM » |
|
Compile time asserts (no, I don't use c++11). The CT_ASSERT_INFUNC stops warnings about unused variables when you use it in a function scope. #define CT_ASSERT(cond) extern int s_iCompileTimeAssert[(cond) ? 1 : -1] #define CT_ASSERT_INFUNC(cond) extern int s_iCompileTimeAssert[(cond) ? 1 : -1];(void)s_iCompileTimeAssert
|
|
|
Logged
|
|
|
|
ThemsAllTook
|
|
« Reply #9 on: April 08, 2015, 11:39:15 AM » |
|
Definitely this one: OFFSET_OF( data, member ) ((int)(&((data*)0)->member)) There's a version of that (called offsetof()) in stddef.h, if you'd prefer a standard implementation.
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #10 on: April 08, 2015, 02:05:43 PM » |
|
To avoid redefining stuff that gets included more than once, I do, in every .hpp file:
#ifndef FILENAME_WITHOUT_EXTENSION #define FILENAME_WITHOUT_EXTENSION
//code goes here
#endif
Everyone does that. It's called a header guard. With a lot of modern compilers you can just use #pragma once. I know it works in Visual Studio (at least 2012 and newere, but I'm pretty sure even 2010 supports it) as well as Xcode (for some number of recent versions). I use #pragma once because It's just so much nicer and cleaner than header guards. Hey, that's right. I haven't seen or heard about that in many years.
|
|
|
Logged
|
|
|
|
Average Software
|
|
« Reply #11 on: April 08, 2015, 02:46:17 PM » |
|
Definitely this one: OFFSET_OF( data, member ) ((int)(&((data*)0)->member)) While this may seem to be working, I believe this actually strays into undefined behavior since you're technically derefencing a null pointer.
|
|
|
Logged
|
What would John Carmack do?
|
|
|
Whiskas
|
|
« Reply #12 on: April 08, 2015, 02:49:24 PM » |
|
A thing I do, I know it's quite unusual but it makes my headers more readable (for me at least): #define PRIVATE_METHODS private: #define PUBLIC_METHODS public: // ... The thing is the keywords are the same colour as all the basic types, so since defines have a different colour they stand out visually. The rest is bonus, I just like organizing all my headers the same way and things to be specific. Also some lazy programmer defines for the recurrent casts, saves a few keystrokes: #define TO_FLOAT(x) static_cast<float>(x) #define TO_INT(x) static_cast<int>(x) // ... Useful unused macro to get rid of warnings: #define UNUSED(x) (void)x I also have lots of macros when using V8 since it saves a lot of time when binding stuff.
|
|
« Last Edit: April 08, 2015, 02:56:03 PM by Whiskas »
|
Logged
|
|
|
|
oahda
|
|
« Reply #13 on: April 09, 2015, 01:02:01 AM » |
|
A thing I do, I know it's quite unusual but it makes my headers more readable (for me at least): #define PRIVATE_METHODS private: #define PUBLIC_METHODS public: // ... The thing is the keywords are the same colour as all the basic types, so since defines have a different colour they stand out visually. The rest is bonus, I just like organizing all my headers the same way and things to be specific. I solve that by indentation.
|
|
|
Logged
|
|
|
|
Whiskas
|
|
« Reply #14 on: April 09, 2015, 04:17:06 AM » |
|
A thing I do, I know it's quite unusual but it makes my headers more readable (for me at least): #define PRIVATE_METHODS private: #define PUBLIC_METHODS public: // ... The thing is the keywords are the same colour as all the basic types, so since defines have a different colour they stand out visually. The rest is bonus, I just like organizing all my headers the same way and things to be specific. I solve that by indentation. Yeah I used to do that, but I'm the kind of guy who's bothered by the double unindent at the end of the class
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #15 on: April 09, 2015, 04:18:10 AM » |
|
A thing I do, I know it's quite unusual but it makes my headers more readable (for me at least): #define PRIVATE_METHODS private: #define PUBLIC_METHODS public: // ... The thing is the keywords are the same colour as all the basic types, so since defines have a different colour they stand out visually. The rest is bonus, I just like organizing all my headers the same way and things to be specific. I solve that by indentation. Yeah I used to do that, but I'm the kind of guy who's bothered by the double unindent at the end of the class Put a friend class at the same indentation level as the visibility modifiers at the bottom for good measure. But yeah, that doesn't bother me. I often have things like an if with a for in it with another if in it and then just a single statement, in which case I don't use any curly braces, and that makes several indentation levels suddenly jump back a few steps the next line.
|
|
|
Logged
|
|
|
|
InfiniteStateMachine
|
|
« Reply #16 on: April 09, 2015, 05:44:55 AM » |
|
A thing I do, I know it's quite unusual but it makes my headers more readable (for me at least): #define PRIVATE_METHODS private: #define PUBLIC_METHODS public: // ... The thing is the keywords are the same colour as all the basic types, so since defines have a different colour they stand out visually. The rest is bonus, I just like organizing all my headers the same way and things to be specific. I solve that by indentation. I saw some code the other day where someone must have come from a java/c# background because in the class the declarations were like this : private : void someFunct(); public : void someFunc(); private : void someFunc2(); It was a little weird, I didn't hate it but I wouldn't do it myself. I prefer the region style of c++. Also I use #pragma once whenever I can over ifdefs. IIRC pragma means a preprocessor command that's an extension but in reality I haven't come across a compiler that doesn't support it. Do custom ones count? I like some of the ones that do a lot of the boiler plate work. For example if you have some sort of gameobject system where an object must always be non-copyable and have some custom typedefed smart pointer you just add 2 macros along the lines of DECLARE_GAMEOBJECT(name) and DEFINE_GAMEOBJECT(name,base). I used to hate them but I've come to embrace them.
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #17 on: April 09, 2015, 06:05:43 AM » |
|
I had honestly forgotten about the existence of #pragma once for years until this thread, but I'll just stick to the old style, being paranoid I'll bump into a compiler that doesn't support it or something. I waited way too long to start using C++0x (i.e. C++11 for me ATM) too. Maybe for my next project. Don't wanna go and change everything now. It doesn't bother me. I actually started typing public with no colon at all in C++ the other day and then it took me a little while to find the error. Would've made more sense if I'd been using Unity just recently, but it had been weeks and I had been programming in C++ the same day…
|
|
|
Logged
|
|
|
|
Cheesegrater
Level 1
|
|
« Reply #18 on: April 09, 2015, 06:38:55 AM » |
|
Most code I see has both include guards and #pragma once. Compilers ignore any pragmas they don't support, so an extra one is harmless.
#pragma once is always worth doing because it causes the preprocessor to stop scanning the file immediately. The saved build time can add up in large projects.
|
|
|
Logged
|
|
|
|
oahda
|
|
« Reply #19 on: April 09, 2015, 06:59:59 AM » |
|
Oh. That's not as much work as going through and replacing header guards. Might do that.
|
|
|
Logged
|
|
|
|
|