IT story

들여 쓰기 #defines

hot-time 2020. 8. 28. 08:03
반응형

들여 쓰기 #defines


#defines 등은 일반적으로 들여 쓰기되지 않는다는 것을 알고 있습니다. 왜?

나는 현재 #defines, #ifdefs, #elses, #endifs 등 끔찍한 혼합이있는 일부 코드에서 작업하고 있습니다 .이 모든 것들은 종종 일반 C 코드와 섞여 있습니다. #defines를 들여 쓰지 않으면 읽기가 어렵습니다. 그리고 들여 쓰기 된 코드와 들여 쓰기되지 않은 #defines 의 혼합은 악몽입니다.

#defines를 들여 쓰지 않으면 어떤 이점이 있습니까? 들여 쓰기를하면 나쁜 사람이 되나요? 이게 훨씬 멋지지 않나요?

#ifdef SDCC
    #if DEBUGGING == 1
        #if defined (pic18f2480)
            #define FLASH_MEMORY_END 0x3DC0
        #elif defined (pic18f2580)
            #define FLASH_MEMORY_END 0x7DC0
        #else
            #error "Can't set  up flash memory end!"
        #endif
    #else
        #if defined (pic18f2480)
            #define FLASH_MEMORY_END 0x4000
        #elif defined (pic18f2580)
            #define FLASH_MEMORY_END 0x8000
        #else
            #error "Can't set  up flash memory end!"
        #endif
    #endif
#else
    #if DEBUGGING == 1
        #define FLASH_MEMORY_END 0x7DC0
    #else
        #define FLASH_MEMORY_END 0x8000
    #endif
#endif

ANSI C 이전 전처리 기는 줄의 시작과 "#"문자 사이에 공백을 허용하지 않았습니다. 선행 "#"은 항상 첫 번째 열에 배치되어야합니다.

현재 ANSI C 이전 컴파일러는 존재하지 않습니다. 선호하는 스타일 ( "#"앞의 공백 또는 "#"과 식별자 사이의 공백)을 사용하십시오.

http://www.delorie.com/gnu/docs/gcc/cpp_48.html


일부가 이미 말했듯이 일부 Pre-ANSI 컴파일러는 #을 줄의 첫 번째 문자로 요구했지만 de 전 처리기 지시문을 첨부 할 필요가 없었기 때문에 이러한 방식으로 들여 쓰기가 이루어졌습니다.

#ifdef SDCC
#  if DEBUGGING == 1
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x3DC0
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x7DC0
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  else
#    if defined (pic18f2480)
#      define FLASH_MEMORY_END 0x4000
#    elif defined (pic18f2580)
#      define FLASH_MEMORY_END 0x8000
#    else
#      error "Can't set  up flash memory end!"
#    endif
#  endif
#else
#  if DEBUGGING == 1
#    define FLASH_MEMORY_END 0x7DC0
#  else
#    define FLASH_MEMORY_END 0x8000
#  endif
#endif

나는 종종 오래된 유닉스 헤더에서이 스타일을 보았지만, 그런 코드에서는 구문 색상이 종종 실패하기 때문에 싫어합니다. 전 처리기 지시문에 매우 눈에 띄는 색상을 사용하여 눈에 띄도록합니다 (메타 수준이므로 정상적인 코드 흐름의 일부가되어서는 안됩니다). SO가 유용한 방식으로 시퀀스를 색칠하지 않는다는 것을 알 수 있습니다.


Regarding the parsing of preprocessor directives, the C99 standard (and the C89 standard before it) were clear about the sequence of operations performed logically by the compiler. In particular, I believe it means that this code:

/* */ # /* */ include /* */ <stdio.h> /* */

is equivalent to:

#include <stdio.h>

For better or worse, GCC 3.4.4 with '-std=c89 -pedantic' accepts the comment-laden line, at any rate. I'm not advocating that as a style - not for a second (it is ghastly). I just think that it is possible.

ISO/IEC 9899:1999 section 5.1.1.2 Translation phases says:

  1. [Character mapping, including trigraphs]

  2. [Line splicing - removing backslash newline]

  3. The source file is decomposed into preprocessing tokens and sequences of white-space characters (including comments). A source file shall not end in a partial preprocessing token or in a partial comment. Each comment is replaced by one space character. New-line characters are retained. Whether each nonempty sequence of white-space characters other than new-line is retained or replaced by one space character is implementation-defined.

  4. Preprocessing directives are executed, macro invocations are expanded, [...]

Section 6.10 Preprocessing directives says:

A preprocessing directive consists of a sequence of preprocessing tokens that begins with a # preprocessing token that (at the start of translation phase 4) is either the first character in the source file (optionally after white space containing no new-line characters) or that follows white space containing at least one new-line character, and is ended by the next new-line character.

The only possible dispute is the parenthetical expression '(at the start of translation phase 4)', which could mean that the comments before the hash must be absent since they are not otherwise replaced by spaces until the end of phase 4.

As others have noted, the pre-standard C preprocessors did not behave uniformly in a number of ways, and spaces before and in preprocessor directives was one of the areas where different compilers did different things, including not recognizing preprocessor directives with spaces ahead of them.

It is noteworthy that backslash-newline removal occurs before comments are analyzed. Consequently, you should not end // comments with a backslash.


I don't know why it's not more common. There are certainly times when I like to indent preprocessor directives.

One thing that keeps getting in my way (and sometimes convinces me to stop trying) is that many or most editors/IDEs will throw the directive to column 1 at the slightest provocation. Which is annoying as hell.


These days I believe this is mainly a choice of style. I think at one point in the distant past, not all compilers supported the notion of indenting preprocessor defines. I did some research and was unable to back up that assertion. But in any case, it appears that all modern compilers support the idea of indenting pre-processor macro. I do not have a copy of the C or C++ standard though so I do not know if this is standard behavior or not.

As to whether or not it's good style. Personally, I like the idea of keeping them all to the left. It gives you a consistent place to look for them. Yeah it can get annoying when there are very nested macros. But if you indent them, you'll eventually end up with even weirder looking code.

#if COND1
void foo() {
  #if COND2
  int i;
    #if COND3
  i = someFunction()
  cout << i << eol;
    #endif
  #endif
}
#endif

For the example you've given it may be appropriate to use indentation to make it clearer, seeing as you have such a complex structure of nested directives.

Personally I think it is useful to keep them not indented most of the time, because these directives operate separately from the rest of your code. Directives such as #ifdef are handled by the pre-processor, before the compiler ever sees your code, so a block of code after an #ifdef directive may not even be compiled.

Keeping directives visually separated from the rest of your code is more important when they are interspersed with code (rather than a dedicated block of directives, as in the example you give).


I'm working in some code at the moment which has a horrible mixture of #defines, #ifdefs, #elses, #endifs, #etc. All these often mixed in with normal C code. The non-indenting of the #defines makes them hard to read. And the mixture of indented code with non-indented #defines is a nightmare.

A common solution is to comment the directives, so that you easily know what they refer to:

#ifdef FOO
/* a lot of code */
#endif /* FOO */

#ifndef FOO
/* a lot of code */
#endif /* not FOO */

참고URL : https://stackoverflow.com/questions/789073/indenting-defines

반응형