Shaders and the mystery of multitude of different conditional define checks

Hi,

So i’m in the process of writing a shader and using various references to add aspects such as Keyword defines as well as ‘normal’ defines(?) and come to the realization that Unity shaders seem to use a multitude of different types of conditionals checks that has left me somewhat puzzled.

Now admittedly i’ve not actually done any testing with what I’ve found to see if there is any reason and I could easily surmise some plausible explanation, but its late, so I’m hoping someone else might have the answers.

So just looking at the new standard shader I can see three distinct formats

#if defined ( _MYDEFINE )

#ifdef ANOTHERDEFINE

#if YETANOTHERDEFINE

So does anyone have any idea why there are three different and distinct formats for conditional define checks? Is there any specific reason for them? Are they interchangeable?

They all do different thing (but could be used to express similar thing in some case)

  • #if test the value of what come next :
#define FOO 1
#define BAR 0

#if FOO
//compiled
#endif

#if BAR
//not compiled
#endif
  • define return 1 if the macro is defined, and 0 if not
#if defined(FOO)
//compile
#endif

#if define(BAR)
//compile too! BAR value is 0, but it is defined, so defined "return" 1
#endif

#if defined(ATUIN)
//don't compile, that macro is not define
#endif
  • ifdef is a combination of the two kind, but don’t allow composite check
#ifdef FOO
//compile
#endif

#ifdef BAR
//compile
#endif

//ERROR! Can't put a preprocessor directive in the middle of the line
#ifdef FOO && #ifndef BAR
#endif
//So in that case use defined()
#if defined(FOO) && !defined(BAR)
//won't compile, as BAR IS defined
#endif
13 Likes

Thanks for the reply, makes much more sense now.

You wrote #if defined(FOO) above, and #if define(FOO). Is there any difference between #if defined and #if define?

@Boyce_Lig it’s a typo. #if defined(FOO) is the correct form for the conditional.