programing

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

kingscode 2022. 7. 14. 22:24
반응형

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

나는 컴퓨터 공학과 1학년이고 교수님이 말했다.#define업계 표준에서는 금지되어 있습니다.#if,#ifdef,#else및 기타 몇 가지 프리프로세서 지시사항을 참조해 주십시오.그는 예상치 못한 행동 때문에 금지라는 단어를 사용했다.

이게 맞습니까?그렇다면 왜?

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

처음 들어봐요.

아니요.#define널리 사용되고 있습니다.때로는 너무 널리 쓰이기도 하지만 분명히 쓰이기도 한다.C규격에 따라 매크로 사용이 의무화되어 있는 곳도 있습니다.그것은 쉽게 피할 수 없습니다.를 들어, "7.5 Errors"는 다음과 같습니다.

매크로는

     EDOM
     EILSEQ
     ERANGE

유형으로 정수 상수식으로 확장됩니다.int, 개별 양의 값 및 에서 사용하기에 적합한 값#if지시의 전처리

따라서 모든 업계 표준이 C 프리프로세서 매크로 디렉티브의 사용을 금지하고 있는 것은 아닙니다.단, C 프리프로세서의 사용을 완전히 금지하는 것은 없지만 다양한 조직에서는 '베스트 프랙티스' 또는 '코드 가이드라인' 규격이 있습니다.C 프리프로세서의 사용을 완전히 금지하고 있는 것은 아닙니다.이것은 C의 선천적인 일부이기 때문에 완전히 피할 수 없습니다.종종 이러한 표준은 안전이 중요한 지역에서 일하는 사람들을 위한 것입니다.

MISRA C(2012) 표준을 체크할 수 있는 하나의 표준.그것은 물건을 금지하는 경향이 있지만, 그것조차도 그것을 인정하고 있다.#define(제8.20절, 규칙 20.1~20.14는 C 프리프로세서를 포함한다.)

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

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

이 도입문 뒤에 나오는 설명에서는 함수 매크로의 허용 가능한 사용에 대해 설명합니다.

CERT C Coding Standard에는 프리프로세서 사용에 관한 가이드라인이 다수 기재되어 있어 프리프로세서 사용을 최소한으로 억제할 필요가 있지만 사용을 금지하지는 않습니다.

Strustrup은 C++에서 프리프로세서를 무관하게 만들고 싶지만, 아직 그런 일은 일어나지 않았습니다.Peternotes에 따르면 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 에서는 사용할 수 없는 장소에서 사용할 수 있습니다.여기서의 문제에 대해서는, 「vs」와「vs」도 참조해 주세요.

프리프로세서의 사용을 최소한으로 억제하는 것이 좋습니다.사용되는 만큼만이라도 악용되는 경우가 많습니다(C 프리프로세서를 사용할 수 있는 정도에 대해서는 Boost 프리프로세서 「라이브러리」를 참조해 주세요).

요약

프리프로세서는 C의 일부이며,#define그리고.#if등을 완전히 피할 수 없습니다.그 문제에 그 교수에 의해서 그 진술은 일반적으로:#를 산업 표준#만약,#ifdef,# 다른 및 몇가지 다른 매크로는 over-statement에서 최상의 것과 함께 금지되어 있지만 구체적인 산업 표준(지만 질문에 이 기준을 명시적 참조와/IEC9899 포함시키지 마세요 지지할 수 있는일 수 있습니다. 2011년 — C유효하지 않다표준 cm이다.


David Hammen은 C 프리프로세서의 사용을 제한하는 것(다이나믹 메모리 할당의 사용 제한, 재귀 금지 등)을 포함한 많은 사람들이 C에서 사용하는 많은 것을 금지하는 특정 C 코딩 표준(JPL C 코딩 표준)에 대한 정보를 제공하고 있습니다.그 이유를 읽고 그 이유를 판단합니다.이유와 관련이 있습니다.)

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

실제로,#include헤더 파일의 가드는 일반적인 기술 중 하나이며, 대부분의 경우 필수이며 승인된 코딩 가이드라인에 따라 권장됩니다.라고 주장하는 사람도 있다#pragma once그 대안이지만 문제는#pragma once- 정의상, 플러그마는 컴파일러 고유의 확장을 위한 표준으로 제공되는 후크이기 때문에 - 다수의 컴파일러에 의해 지원되는 경우에도 비표준입니다.

즉, 업계 가이드라인과 권장되는 프랙티스가 다수 존재하기 때문에 매크로 이외의 모든 사용을 적극적으로 금지하고 있습니다.#include(범위 등에 관계없이) 매크로에 의해 발생하는 문제 때문에 보호됩니다.C++ 개발에서는 C 개발보다 매크로의 사용이 더욱 강조되고 있습니다.

예를 들어, 정당성을 입증하는 등 합법적으로 사용하는 것이 여전히 가능하기 때문에, 어떤 것을 사용하는 것을 권장하는 것은 그것을 금지하는 것과 같지 않다.

일부 코딩 규격은 다음을 권장하거나 금지할 수 있습니다.#define예를 들어 인수를 사용하는 기능성 매크로를 만듭니다.

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

a) 그러한 매크로는 타입 세이프가 아니고, b) 누군가가 필연적으로 글을 쓸 이기 때문이다.SQR(x++)나쁜 쥬주죠.

일부 규격은 다음을 권장하거나 금지할 수 있습니다.#ifdef조건부 컴파일용.예를 들어, 다음 코드는 조건 컴파일을 사용하여 적절하게 인쇄합니다.size_tC99 이후의 경우, C99 및 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 이후 버전 등 모듈을 2회 구현하도록 요구할 수 있습니다.

/* 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 C 표준의 오류에서는 매크로를 사용해야 합니다.

1 헤더<errno.h>에, 에러 상태의 리포트에 관한 매크로를 몇개 정의하고 있습니다.

2 매크로는

EDOM
EILSEQ
ERANGE

유형으로 정수 상수식으로 확장됩니다.int, 개별 양의 값 및 에서 사용하기에 적합한 값#if전처리 지시

errno

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

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

아니요.#define금지되어 있지 않습니다.의 오용#define단, 눈살을 찌푸릴 수 있습니다.

예를 들어,

#define DEBUG

나중에 조건부 컴파일을 위해 코드 일부를 지정할 수 있도록 코드 내에서 다음을 사용합니다.#ifdef DEBUG, 디버깅 전용입니다.제정신이라면 이런 걸 금지하고 싶진 않을 거야정의된 매크로#define또한 플랫폼별 코드 컴파일을 활성화/비활성화하기 위해 휴대용 프로그램에서 광범위하게 사용됩니다.

단, 다음과 같은 것을 사용하고 있다면

#define PI 3.141592653589793

당신의 선생님은 당연히 선언하는 것이 훨씬 낫다고 지적할 것이다.PI예를 들어 다음과 같은 적절한 유형의 상수로 간주합니다.

const double PI = 3.141592653589793;

컴파일러가 언제 타입 체크를 할 수 있도록 하기 때문에PI사용됩니다.

마찬가지로(위의 John Bode에 의해 언급되었듯이), 특히 템플릿을 사용할 수 있는 C++에서는 함수형 매크로의 사용이 거부될 수 있습니다.그래서 대신

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

사용을 검토하다

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

아니면 C++에서는 더 낫습니다.

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

다시 한 번 말씀드리지만, 프리프로세서 대신 언어의 기능을 사용함으로써 컴파일러가 더 나은 코드를 생성할 수 있습니다.

코딩 경험이 충분하면 언제 사용하는 것이 적절한지 정확히 알 수 있습니다.#define그때까지는 선생님이 일정한 규칙과 코딩 기준을 부과하는 것이 좋다고 생각합니다만, 바람직하게는 그들 자신이 그 이유를 알고 설명할 수 있어야 합니다.전면 금지#define말도 안 돼요

그건 완전히 거짓이야, 매크로가 C에서 많이 쓰이고 있어.초보자들은 종종 그것들을 나쁘게 사용하지만 그것이 그들을 산업으로부터 금지할 이유는 아니다.전형적인 잘못된 사용법은#define succesor(n) n + 1기대하시는 경우2 * successor(9)20을 주는 것은 틀렸다. 왜냐하면 그 표현은 로 번역될 것이기 때문이다2 * 9 + 1즉, 20이 아니라 19입니다.괄호를 사용하여 원하는 결과를 얻습니다.

아니요, 금지되지 않았어요.그리고 사실, 그것 없이는 사소한 멀티 플랫폼 코드를 실행하는 것은 불가능합니다.

아니, 교수님이 틀렸거나 네가 잘못 들은 게 아니야.

#define는 프리프로세서 매크로입니다.조건부 컴파일 및 일부 표기법에는 프리프로세서 매크로가 필요합니다.이것은 단순히 C언어로 구축되지 않습니다.예를 들어, 최근의 C 표준, 즉 C99에서는 부란에 대한 지원이 추가되었습니다.다만, 언어에 의해서 「원어민」이 아니고, 프리프로세서에 의해서 서포트되고 있습니다.#defines. stdbool.h 참조

매크로는 GNU 랜드 C에서 상당히 많이 사용되고 있으며 조건부 프리프로세서 명령어 없이는 동일한 소스 파일의 여러 포함을 적절하게 처리할 수 없기 때문에 나에게는 필수적인 언어 기능처럼 보입니다.

당신의 클래스는 실제로 C++를 사용하고 있을지도 모릅니다만, 많은 사람이 C++를 사용하고 있지 않습니다.다른 언어이기 때문에 C와 구별해야 합니다.매크로에 대해서는 말할 수 없습니다.아니면 교수님이 수업시간에 그들을 금지시키겠다는 걸 의미했을 수도 있어요.어쨌든 SO 커뮤니티에서는 그가 말하는 표준이 무엇인지에 관심이 있을 것입니다. 왜냐하면 모든 C 표준이 매크로 사용을 지원한다고 확신하기 때문입니다.

지금까지의 모든 답변과 달리, 신뢰성이 높은 컴퓨팅에서는 프리프로세서 디렉티브의 사용이 금지되는 경우가 많습니다.여기에는 두 가지 예외가 있는데, 이러한 조직에서는 이 두 가지를 사용하도록 의무화되어 있습니다.이것들은#include헤더 파일에 include guard를 사용할 수 있습니다.이러한 종류의 금지는 C가 아닌 C++에서 발생할 가능성이 높습니다.

를 들어, 16.1.1 프리프로세서는 인크루드 가드를 실장하고 인크루드 가드를 포함한 헤더파일을 실장하는 경우에만 사용합니다.

또 다른 예로는 이번에는 C++가 아닌 C의 경우: JPL Institutional Coding Standard for the C Programming Language 입니다.이 C코딩 규격은 프리프로세서의 사용을 완전히 금지하는 수준까지는 이르지 않지만 거의 비슷합니다.구체적으로 말하면

규칙 20(프리프로세서 사용) C 프리프로세서의 사용은 파일 포함 및 단순 매크로로 제한됩니다.[10의 힘 8]


나는 그 기준을 묵인하지도 비난하지도 않는다.하지만 그들이 존재하지 않는다고 말하는 것은 터무니없다.

C 코드가 C++ 코드와 상호 운용되도록 하려면 함수 선언과 같이 외부에서 볼 수 있는 기호를extern "C"네임스페이스.이것은 조건부 컴파일을 사용하여 실행되는 경우가 많습니다.

#ifdef __cplusplus
extern "C" {
#endif

/* C header file body */

#ifdef __cplusplus
}
#endif

헤더 파일을 보면 다음과 같은 것을 알 수 있습니다.

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

이러한 정의는 허용될 뿐만 아니라 헤더 파일이 파일에서 참조될 때마다 별도로 포함되므로 본질적으로 매우 중요합니다.즉, 정의가 없으면 가드 사이에 있는 모든 것을 여러 번 재정의할 수 있습니다.최선의 경우는 컴파일 할 수 없고, 최악의 경우는 나중에 왜 코드가 원하는 대로 동작하지 않는지 머리를 긁적거리게 됩니다.

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.

ReferenceURL : https://stackoverflow.com/questions/34496418/is-define-banned-in-industry-standards

반응형