Search Unity

Shaders and the mystery of multitude of different conditional define checks

Discussion in 'Shaders' started by Noisecrime, Apr 16, 2015.

  1. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    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?
     
  2. UnityGuillaume

    UnityGuillaume

    Unity Technologies

    Joined:
    Mar 16, 2015
    Posts:
    123
    They all do different thing (but could be used to express similar thing in some case)

    - #if test the value of what come next :


    Code (CSharp):
    1. #define FOO 1
    2. #define BAR 0
    3.  
    4. #if FOO
    5. //compiled
    6. #endif
    7.  
    8. #if BAR
    9. //not compiled
    10. #endif
    11.  
    - define return 1 if the macro is defined, and 0 if not

    Code (CSharp):
    1. #if defined(FOO)
    2. //compile
    3. #endif
    4.  
    5. #if define(BAR)
    6. //compile too! BAR value is 0, but it is defined, so defined "return" 1
    7. #endif
    8.  
    9. #if defined(ATUIN)
    10. //don't compile, that macro is not define
    11. #endif
    - ifdef is a combination of the two kind, but don't allow composite check


    Code (CSharp):
    1. #ifdef FOO
    2. //compile
    3. #endif
    4.  
    5. #ifdef BAR
    6. //compile
    7. #endif
    8.  
    9. //ERROR! Can't put a preprocessor directive in the middle of the line
    10. #ifdef FOO && #ifndef BAR
    11. #endif
    12. //So in that case use defined()
    13. #if defined(FOO) && !defined(BAR)
    14. //won't compile, as BAR IS defined
    15. #endif
     
  3. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,054
    Thanks for the reply, makes much more sense now.
     
  4. Boyce_Lig

    Boyce_Lig

    Joined:
    Mar 5, 2019
    Posts:
    4
    You wrote `#if defined(FOO)` above, and `#if define(FOO)`. Is there any difference between `#if defined` and `#if define`?
     
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,019
    @Boyce_Lig it's a typo. `#if defined(FOO)` is the correct form for the conditional.