programing tip

산업 표준에서 #define이 금지되어 있습니까?

itbloger 2020. 11. 6. 07:54
반응형

산업 표준에서 #define이 금지되어 있습니까?


나는 첫 해 컴퓨터 과학 학생입니다 내 교수 #define와 함께 업계 표준의 금지 #if, #ifdef, #else, 그리고 몇 가지 다른 처리기 지시문. 그는 예기치 않은 행동 때문에 "금지"라는 단어를 사용했습니다.

정확합니까? 그렇다면 왜?

실제로 이러한 지침의 사용을 금지하는 표준이 있습니까?


먼저 들어 봤습니다.

아니; #define등등 널리 사용됩니다. 때로는 너무 널리 사용되지만 확실히 사용됩니다. C 표준에서 매크로 사용을 요구하는 곳이 있습니다. 쉽게 피할 수 없습니다. 예를 들어 §7.5 오류<errno.h> 는 다음과 같습니다.

매크로는

     EDOM
     EILSEQ
     ERANGE

type int, 뚜렷한 양수 값을 가진 정수 상수 표현식으로 확장 되며 #if전처리 지시문 에 사용하기에 적합 합니다.

이를 감안할 때 모든 산업 표준이 C 전 처리기 매크로 지시문의 사용을 금지하는 것은 아닙니다. 그러나 C 전 처리기의 사용에 대한 제한을 규정하는 다양한 조직의 '모범 사례'또는 '코딩 지침'표준이 있지만, C 전 처리기 사용을 완전히 금지하지는 않습니다. 이는 C의 타고난 부분이며 완전히 피할 수 없습니다. 종종 이러한 표준은 안전이 중요한 영역에서 일하는 사람들을위한 것입니다.

MISRA C (2012) 표준을 확인할 수있는 표준 중 하나입니다 . 그것은 무언가를 금지하는 경향이 있지만 #defineet al이 때때로 필요하다는 것을 인식하는 것조차도 (섹션 8.20, 규칙 20.1에서 20.14까지 C 전처리기를 다룹니다).

NASA GSFC (Goddard Space Flight Center) C 코딩 표준은 간단히 다음과 같이 말합니다.

매크로는 필요한 경우에만 사용해야합니다. 매크로를 과도하게 사용하면 코드가 더 이상 표준 C처럼 읽거나 동작하지 않기 때문에 코드를 읽고 유지하기가 더 어려워 질 수 있습니다.

그 소개문 이후의 논의는 함수 매크로의 허용 가능한 사용을 보여줍니다.

CERT C 코딩 표준 전처리의 사용에 대한 가이드 라인을 가지고 있습니다, 당신은 전처리의 사용을 최소화해야하지만, 그것의 사용을 금지하지 않는 것을 의미한다.

Stroustrup은 전처리기를 C ++에서 무관하게 만들고 싶지만 아직 발생하지 않았습니다. Peter가 언급 했듯이 2005 년경 JSF AV C ++ 코딩 표준 ( Joint Strike Fighter, Air Vehicle ) 과 같은 일부 C ++ 표준 은 C 전 처리기의 최소 사용을 요구합니다. 본질적으로 JSF AV C ++ 규칙 은 단일 헤더의 다중 포함을 방지 #include하는 #ifndef XYZ_H/ #define XYZ_H/… / #endif댄스로 제한합니다 . C ++에는 C에서 사용할 수없는 몇 가지 옵션이 있습니다. 특히 C에서 사용할 수없는 곳에서 사용할 수있는 형식화 된 상수를 더 잘 지원합니다. 문제에 대한 논의 static constvs #definevsenum참조하십시오 .

전 처리기의 사용을 최소화하는 것이 좋습니다. 최소한 사용하는만큼 남용되는 경우가 많습니다 ( C 전처리기로 얼마나 멀리 갈 수 있는지에 대한 설명은 Boost 전 처리기 '라이브러리'를 참조하십시오 ).

요약

전처리 기는 C의 필수 부분 #define이며 #if등은 완전히 피할 수 없습니다. 질문에 교수의 말씀은 일반적으로 유효하지 않습니다 #define와 함께 업계 표준의 금지 #if, #ifdef, #else, 그리고 몇 가지 다른 매크로가 최상의 오버 문이지만, 특정 산업 표준에 명시 적으로 참조하여 지원 가능한 수 있습니다 (하지만 문제의 표준에는 ISO / IEC 9899 : 2011 (C 표준)이 포함되어 있지 않습니다.


참고 데이비드 Hammen가정보를 제공하고 더 - 하나의 특정 C는 표준 코딩에 대한 표준 코딩 JPL C 많은 사람들이 C 프리 프로세서의 사용을 제한 (동적 메모리의 사용을 제한 포함, C에서 사용하는 많은 것들을 금지 - 할당 및 재귀 금지-그 이유를 읽고 그 이유가 귀하와 관련이 있는지 결정하십시오).


아니요, 매크로 사용은 금지되지 않습니다.

사실, #include헤더 파일에서 가드를 사용 하는 것은 종종 필수이며 승인 된 코딩 지침에서 권장하는 일반적인 기술 중 하나입니다. 일부 사람들은 이것이 #pragma once대안 이라고 주장 하지만, 문제는 #pragma once정의상 pragma가 컴파일러 특정 확장에 대한 표준에 의해 제공되는 후크이기 때문에 여러 컴파일러에서 지원하더라도 표준 이 아니라는 것입니다.

즉, #include매크로가 도입하는 문제 (범위를 존중하지 않는 등)로 인해 가드 이외의 모든 매크로 사용을 적극적으로 억제하는 많은 업계 지침과 권장 관행이 있습니다. C ++ 개발에서 매크로 사용은 C 개발에서보다 훨씬 더 강하게 눈살을 찌푸립니다.

예를 들어 정당성을 문서화하여 합법적으로 사용할 수 있기 때문에 무언가를 사용하지 않는 것은 금지하는 것과 다릅니다.


일부 코딩 표준은 인수 #define를 사용하는 함수형 매크로 를 만드는 데 사용하는 것을 권장하지 않거나 금지 할 수 있습니다.

#define SQR(x) ((x)*(x))

A) 등의 매크로 입력 - 안전하지 않기 때문에, 그리고 B)을 누군가는 것이다 필연적으로 쓰기 SQR(x++)나쁜 주주이다.

일부 표준은 #ifdef조건부 컴파일 s 사용을 권장하지 않거나 금지 할 수 있습니다 . 예를 들어 다음 코드는 조건부 컴파일을 사용하여 size_t을 올바르게 인쇄 합니다. 들어 C99 나중에, 당신은 사용 %zu변환 지정자; 대한 C89 및 이전 버전 사용 %lu하고 값을 캐스팅 unsigned long:

#if __STDC_VERSION__ >= 199901L
#  define SIZE_T_CAST
#  define SIZE_T_FMT "%zu"
#else
#  define SIZE_T_CAST (unsigned long)
#  define SIZE_T_FMT "%lu"
#endif
...
printf( "sizeof foo = " SIZE_T_FMT "\n", SIZE_T_CAST sizeof foo );

일부 표준에서는 이 작업을 수행하는 대신 모듈을 두 번, C89 및 이전 버전에 대해 한 번, C99 이상에 대해 한 번 구현하도록 요구할 수 있습니다 .

/* C89 version */
printf( "sizeof foo = %lu\n", (unsigned long) sizeof foo );

/* C99 version */
printf( "sizeof foo = %zu\n", sizeof foo );

그런 다음 Make (또는 Ant 또는 사용중인 빌드 도구)가 올바른 버전을 컴파일하고 연결하도록합니다. 말도 잔인한 것,하지만 난의 추적이 불가능 쥐의 둥지이었다 코드를 본 적이이 예제 #ifdef해야 조건부 코드는 별도의 파일로 밖으로 고려하는 것이 있었다합니다.

그러나 전 처리기 문 사용을 완전히 금지회사 나 산업 그룹에 대해서는 알지 못합니다 .


매크로는 "금지"할 수 없습니다. 말도 안돼. 말 그대로.

예를 들어, 섹션 7.5 오류<errno.h>C 표준이 필요 매크로의 사용을 :

1 헤더 <errno.h>는 오류 상태보고와 관련된 여러 매크로를 정의합니다.

2 매크로는

EDOM
EILSEQ
ERANGE

type int, 뚜렷한 양수 값을 가진 정수 상수 표현식으로 확장 되며 #if전처리 지시문 에 사용하기에 적합 합니다.

errno

유형 int및 스레드 로컬 저장 기간 이있는 수정 가능한 lvalue로 확장되며 ,이 값은 여러 라이브러리 함수에 의해 양의 오류 번호로 설정됩니다. 실제 객체에 액세스하기 위해 매크로 정의가 억제되거나 프로그램이 이름으로 식별자를 정의 errno하면 동작이 정의되지 않습니다.

따라서 매크로는 C 필수 부분 일뿐만 아니라 일부 경우 매크로를 사용하지 않으면 정의되지 않은 동작이 발생합니다.


아니요, #define금지되지 않았습니다. #define그러나의 오용은 눈살을 찌푸 릴 수 있습니다.

예를 들어, 다음을 사용할 수 있습니다.

#define DEBUG

나중에 #ifdef DEBUG디버그 목적으로 만을 사용하여 조건부 컴파일을 위해 코드의 일부를 지정할 수 있도록 코드에서 . 나는 그의 올바른 마음을 가진 사람이 이와 같은 것을 금지하고 싶어하지 않을 것이라고 생각합니다. 를 사용하여 정의 된 매크로 #define는 플랫폼 별 코드의 컴파일을 활성화 / 비활성화하기 위해 이식 가능한 프로그램에서도 광범위하게 사용됩니다.

그러나 다음과 같은 것을 사용하는 경우

#define PI 3.141592653589793

당신의 교사는 PI적절한 유형을 가진 상수 로 선언하는 것이 훨씬 낫다는 것을 정당하게 지적 할 수 있습니다 .

const double PI = 3.141592653589793;

as it allows the compiler to do type checking when PI is used.

Similarly (as mentioned by John Bode above), the use of function-like macros may be disapproved of, especially in C++ where templates can be used. So instead of

#define SQ(X) ((X)*(X))

consider using

double SQ(double X) { return X * X; }

or, in C++, better yet,

template <typename T>T SQ(T X) { return X * X; }

Once again, the idea is that by using the facilities of the language instead of the preprocessor, you allow the compiler to type check and also (possibly) generate better code.

Once you have enough coding experience, you'll know exactly when it is appropriate to use #define. Until then, I think it is a good idea for your teacher to impose certain rules and coding standards, but preferably they themselves should know, and be able to explain, the reasons. A blanket ban on #define is nonsensical.


That's completely false, macros are heavily used in C. Beginners often use them badly but that's not a reason to ban them from industry. A classic bad usage is #define succesor(n) n + 1. If you expect 2 * successor(9) to give 20, then you're wrong because that expression will be translated as 2 * 9 + 1 i.e. 19 not 20. Use parenthesis to get the expected result.


No. It is not banned. And truth to be told, it is impossible to do non-trivial multi-platform code without it.


No your professor is wrong or you misheard something.

#define is a preprocessor macro, and preprocessor macros are needed for conditional compilation and some conventions, which aren't simply built in the C language. For example, in a recent C standard, namely C99, support for booleans had been added. But it's not supported "native" by the language, but by preprocessor #defines. See this reference to stdbool.h


Macros are used pretty heavily in GNU land C, and without conditional preprocessor commands there's be no way to properly handle multiple inclusions of the same source files, so that makes them seem like essential language features to me.

Maybe your class is actually on C++, which despite many people's failure to do so, should be distinguished from C as it is a different language, and I can't speak for macros there. Or maybe the professor meant he's banning them in his class. Anyhow I'm sure the SO community would be interested in hearing which standard he's talking about, since I'm pretty sure all C standards support the use of macros.


Contrary to all of the answers to date, the use of preprocessor directives is oftentimes banned in high-reliability computing. There are two exceptions to this, the use of which are mandated in such organizations. These are the #include directive, and the use of an include guard in a header file. These kinds of bans are more likely in C++ rather than in C.

Here's but one example: 16.1.1 Use the preprocessor only for implementing include guards, and including header files with include guards.

Another example, this time for C rather than C++: JPL Institutional Coding Standard for the C Programming Language . This C coding standard doesn't go quite so far as banning the use of the preprocessor completely, but it comes close. Specifically, it says

Rule 20 (preprocessor use) Use of the C preprocessor shall be limited to file inclusion and simple macros. [Power of Ten Rule 8].


I'm neither condoning nor decrying those standards. But to say they don't exist is ludicrous.


If you want your C code to interoperate with C++ code, you will want to declare your externally visible symbols, such as function declarations, in the extern "C" namespace. This is often done using conditional compilation:

#ifdef __cplusplus
extern "C" {
#endif

/* C header file body */

#ifdef __cplusplus
}
#endif

Look at any header file and you will see something like this:

#ifndef _FILE_NAME_H
#define _FILE_NAME_H
//Exported functions, strucs, define, ect. go here
#endif /*_FILE_NAME_H */

These define are not only allowed, but critical in nature as each time the header file is referenced in files it will be included separately. This means without the define you are redefining everything in between the guard multiple times which best case fails to compile and worse case leaves you scratching your head later why your code doesn't work the way you want it to.

The compiler will also use define as seen here with gcc that let you test for things like the version of the compiler which is very useful. I'm currently working on a project that needs to compile with avr-gcc, but we have a testing environment that we also run our code though. To prevent the avr specific files and registers from keeping our test code from running we do something like this:

#ifdef __AVR__
//avr specific code here
#endif

Using this in the production code, the complementary test code can compile without using the avr-gcc and the code above is only compiled using avr-gcc.


If you had just mentioned #define, I would have thought maybe he was alluding to its use for enumerations, which are better off using enum to avoid stupid errors such as assigning the same numerical value twice.

Note that even for this situation, it is sometimes better to use #defines than enums, for instance if you rely on numerical values exchanged with other systems and the actual values must stay the same even if you add/delete constants (for compatibility).

However, adding that #if, #ifdef, etc. should not be used either is just weird. Of course, they should probably not be abused, but in real life there are dozens of reasons to use them.

What he may have meant could be that (where appropriate), you should not hardcode behaviour in the source (which would require re-compilation to get a different behaviour), but rather use some form of run-time configuration instead.

That's the only interpretation I could think of that would make sense.

참고URL : https://stackoverflow.com/questions/34496418/is-define-banned-in-industry-standards

반응형