정적 Constatic vs #syslog
사용하는 것이 좋습니까?static const
보다 큰 값#define
? 상황에 ?니면면 르르 르르 르르 르르?
각 방법의 장점/단점은 무엇입니까?
장 #define
s,const
및 것) (잊어버린 것)enum
사용법에 다름):s(사용법에 따라 다름):
enum
s:- 정수 값에만 사용 가능
- 에서 "C++"에 가 있는 됩니다.
enum class X
됩니다.X::
- 입력되지만 C할 수 단, 이 structure를 지정할 수 로 합니다.로 C+03 입니다. 지정할 수 있습니다)로, C++11은 디폴트로 되어 있습니다.
int
할 수 . - 주소를 가져올 수 없음 - 열거 값이 사용 지점에서 효과적으로 인라인으로 대체되므로 주소가 없습니다.
- 한 사용 증가 - 보다 stronger예 - 다다예예 - )
template <typename T> void f(T t) { cout << ++t; }
열거형을 암묵적 생성자, 캐스팅 연산자 및 사용자 정의 연산자가 있는 클래스로 래핑할 수 있지만 컴파일할 수 없습니다.) - 상수의 되었으므로, 각 each each 、 each 、 each 、 each 、 each 、 each each each each each each each each each each each each each each each each.
template <typename T> void f(T)
때 수 .이러한 은 모두 enum, enum과 됩니다.f(int)
수 있지만(주소 ), 복사가 만약 할 수 .각 함수의 오브젝트 코드는 동일할 수 있지만(주소 오프셋을 무시하는 경우), 컴파일러/링커가 불필요한 복사본을 제거해 줄 것이라고는 생각하지 않습니다만, 만약 당신이 관심을 가지면 컴파일러/링커를 확인할 수 있습니다. - of 값 및에 대한 할 것으로 수 코드에 of/decltype의 numeric_disket을 고려하십시오).
enum { A = 1, B = 2 }
는 - 는A|B
프로그램 로직의 관점에서 "합법적"이라고 생각하십니까?) - 열거형 타이네임은 RTI, 컴파일러 메시지 등의 다양한 위치에 표시될 수 있습니다. - 유용할 수도 있고, 난독화될 수도 있습니다.
- 이 실제로 있지 수 이 필요합니다.또한 enum은 API의 enum입니다.
make
기타 타임스탬프 기반 재컴파일 툴이 변경되면 클라이언트의 재컴파일이 트리거됩니다(부정).
const
s:- 적절한 범위/식별 충돌 문제 적절하게 처리
- 강한, 강한, 강한,
- '칠 요.
#define
#define S std::string("abc")
, 하지 않도록 합니다.
- '칠 요.
- 단일 정의 규칙의 복잡성
- 주소 지정, 주소 지정에 대한 상시 참조 작성 등을 할 수 있습니다.
-
const
두 값 및 합니다. 이 값은 두 가지 사이에 전환되는 경우 작업 및 영향을 최소화합니다. - 구현 파일 내에 값을 배치할 수 있으므로 로컬화된 재컴파일 및 클라이언트 링크만 변경 내용을 선택할 수 있습니다.
#define
s:- "글로벌" 범위/사용의 경합이 발생하기 쉬워 컴파일하기 어려운 문제와 정상적인 오류 메시지가 아닌 예기치 않은 런타임 결과가 발생할 수 있습니다.이를 완화하려면 다음 사항이 필요합니다.
- 길고 불분명하며 중앙에서 조정된 식별자 및/또는 이들 식별자에 대한 액세스는 사용된/현재/Koenig 검색된 네임스페이스, 네임스페이스 별칭 등을 암묵적으로 일치시켜서는 도움이 되지 않습니다.
- trumping best-practice 에서는 템플릿파라미터 식별자를 1글자의 대문자로 할 수 있습니다(숫자 뒤에 숫자를 붙일 수 있습니다).또, 소문자가 없는 식별자의 그 외의 사용은, 통상, 프리프로세서 정의(OS 및 C/C++ 라이브러리 헤더외)용으로 예약되어 있습니다.이는 엔터프라이즈 규모의 프리프로세서 사용을 관리하기 위해 중요합니다.서드파티 라이브러리는 이에 준거할 것으로 예상됩니다.이를 관찰하는 것은 기존 Const 또는 Enum을 정의에서/또는 정의로 이행하는 것을 의미합니다.따라서 "단순한" 재컴파일보다는 클라이언트 소스 코드의 편집이 필요합니다.(개인적으로는 열거의 첫 글자를 대문자로 쓰지만 Const가 아니기 때문에 이 두 가지 사이에서 이행하는 데 시간이 걸릴 수 있습니다.)
- 보다 많은 컴파일 시간 조작 가능: 문자열 리터럴 연결, 문자열화(사이즈 가져오기), 식별자 연결
- 단점은 주어진다는 것이다
#define X "x"
또한 클라이언트 사용률도 있습니다."pre" X "post"
X를 상수가 아닌 실행 시 변경 가능한 변수로 할 필요가 있는 경우 클라이언트코드에 강제적인 편집(재컴파일뿐만 아니라)을 실시합니다만, 그 이행은, 에서 간단하게 실시할 수 있습니다.const char*
또는const std::string
이미 사용자가 연결 작업을 통합하도록 강제하는 경우(예:"pre" + X + "post"
위해서string
)
- 단점은 주어진다는 것이다
- 사용할 수 없다
sizeof
정의된 숫자 리터럴로 직접 - untypeed (GCC는 경고하지 않습니다)
unsigned
) - 일부 컴파일러/링커/커넥터 체인은 식별자를 표시하지 않을 수 있으므로 "커넥터 번호" (커넥터, 무엇이든)를 보는 것으로 끝납니다.
- 주소를 받을 수 없다
- 치환된 값은 #discreted가 생성된 컨텍스트에서 유효한(또는 이산적인) 것은 아닙니다.사용의 각 포인트에서 평가되므로 아직 참조되지 않은 오브젝트를 참조할 수 있습니다.사전 참조가 필요 없는 "정보"에 의존하여 다음과 같은 "정보"를 생성할 수 있습니다.
{ 1, 2 }
어레이 초기화에 사용할 수 있습니다.#define MICROSECONDS *1E-6
등 (절대 추천하지 않습니다!) - 같은 특별한 것
__FILE__
그리고.__LINE__
매크로 치환에 포함시킬 수 있다 - 존재와 가치를 검증할 수 있습니다.
#if
코드를 조건부로 포함하기 위한 문(사전 프로세서에 의해 선택되지 않은 경우 코드를 컴파일할 필요가 없기 때문에 사후 처리 "if"보다 강력함)#undef
-ine, 재정의 등 - 대체 텍스트를 노출해야 합니다.
- 클라이언트용 라이브러리의 매크로가 헤더에 있어야 합니다.
make
기타 타임스탬프 기반 재컴파일 툴이 변경되면 클라이언트의 재컴파일이 트리거됩니다(부정). - 또는 명령줄에서 클라이언트 코드가 재컴파일되는지 확인하기 위해 더욱 주의를 기울여야 합니다(예를 들어 정의를 제공하는 Makefile 또는 스크립트는 종속 항목으로 표시되어야 합니다).
- 클라이언트용 라이브러리의 매크로가 헤더에 있어야 합니다.
- "글로벌" 범위/사용의 경합이 발생하기 쉬워 컴파일하기 어려운 문제와 정상적인 오류 메시지가 아닌 예기치 않은 런타임 결과가 발생할 수 있습니다.이를 완화하려면 다음 사항이 필요합니다.
제 개인적인 의견:
원칙적으로, 나는const
s는 일반적인 사용을 위한 가장 전문적인 옵션이라고 생각합니다(다른 옵션은 이 게으른 프로그래머에게 매력적인 단순함을 가지고 있습니다).
개인적으로 전 프리프로세서를 싫어해서const
.
의 주요 장점#define
프로그램에 저장하기 위해 메모리가 필요하지 않다는 것입니다. 이는 문자 그대로의 값으로 일부 텍스트를 대체하는 것일 뿐입니다.또한 유형이 없으므로 경고를 생성하지 않고 정수 값에 사용할 수 있습니다.
의 장점const
오브젝트에 대한 포인터를 전달해야 하는 상황에서 사용할 수 있습니다.
네가 무슨 말을 하려는지 정확히 모르겠어static
하지만 헤어졌다.만약 당신이 글로벌하게 선언한다면, 나는 그것을 익명의 네임스페이스에 넣을 것이다.static
.예를들면
namespace {
unsigned const seconds_per_minute = 60;
};
int main (int argc; char *argv[]) {
...
}
이것이 C++의 질문이며, 다음과 같은 경우#define
대안으로, 클래스 멤버가 아닌 "글로벌"(즉, 파일 검색) 상수에 관한 것입니다.C++의 상수에 관한 한static const
용장성이 있습니다.C++의 경우const
디폴트로는 내부 링크가 있기 때문에 선언할 필요가 없습니다.static
그래서 정말 중요한 건const
대.#define
.
마지막으로 C++에서는const
가 바람직합니다.적어도 그러한 상수가 입력되고 범위가 지정되기 때문입니다.더 이상 선호할 이유가 없습니다.#define
에 걸쳐서const
예외는 거의 없습니다.
문자열 상수(BTW)는 이러한 예외의 한 예입니다.와 함께#define
d 문자열 상수는 C/C++ 컴파일러의 컴파일 시간 연결 기능을 사용할 수 있습니다.
#define OUT_NAME "output"
#define LOG_EXT ".log"
#define TEXT_EXT ".txt"
const char *const log_file_name = OUT_NAME LOG_EXT;
const char *const text_file_name = OUT_NAME TEXT_EXT;
추신. 만약을 위해, 누군가 이 사건에 대해 언급했을 때,static const
대신해서#define
이것은 보통 C++가 아니라 C에 대해 이야기하고 있다는 것을 의미합니다.이 문제는 태그가 제대로 되어 있는지...
#define
예기치 않은 결과를 초래할 수 있습니다.
#include <iostream>
#define x 500
#define y x + 5
int z = y * 2;
int main()
{
std::cout << "y is " << y;
std::cout << "\nz is " << z;
}
잘못된 결과를 출력합니다.
y is 505
z is 510
그러나 이 값을 상수로 바꾸면 다음과 같습니다.
#include <iostream>
const int x = 500;
const int y = x + 5;
int z = y * 2;
int main()
{
std::cout << "y is " << y;
std::cout << "\nz is " << z;
}
올바른 결과를 출력합니다.
y is 505
z is 1010
그 이유는#define
단순히 텍스트를 바꿉니다.이렇게 하면 작업 순서가 크게 흐트러질 수 있으므로 상수 변수를 사용하는 것이 좋습니다.
항상 프리프로세서등의 추가 툴보다 언어 기능을 사용하는 것을 선호합니다.
ES.31: 상수 또는 "함수"에 매크로 사용 안 함
매크로는 버그의 주요 원인입니다.매크로는 일반적인 범위 및 유형 규칙을 따르지 않습니다.매크로는 일반적인 인수 전달 규칙을 따르지 않습니다.매크로를 사용하면 컴파일러와 다른 것을 볼 수 있습니다.매크로가 있으면 툴 구축이 복잡해집니다.
다른 일이 생겨 C++에 완전히 도달하지 못한 다소 낡고 녹슨 C프로그래머로서 Arduino를 이해하기 위해 노력하고 있는 나의 견해는 간단하다.
#compiler pre-processor 명령어는 컴파일러의 사전 프로세서 명령어로 조건부 컴파일 등에 사용합니다.예를 들어 하드웨어 지정에 대한 이식성을 위해 가능한 대체 데이터 구조를 정의할 필요가 있는 로우 레벨 코드.모듈이 컴파일되고 링크된 순서에 따라 결과가 일관되지 않을 수 있습니다.범위를 글로벌하게 할 필요가 있는 경우는, 적절히 정의해 주세요.
const 및 (static const)는 항상 정적 값 또는 문자열에 이름을 붙일 때 사용해야 합니다.이러한 파일은 입력 및 안전하며 디버거가 완전히 작동할 수 있습니다.
에넘들은 항상 나를 혼란스럽게 해서 나는 그들을 피할 수 있었다.
프리프로세서 디렉티브를 사용한 상수 정의#define
에만 적용하는 것은 권장되지 않습니다.C++
, 단,C
. 이러한 상수에는 유형이 없습니다.에서조차C
를 사용하도록 제안되었습니다.const
상수의 경우.
여기를 참조해 주세요: static const와 define
통상, const 선언(고정적일 필요는 없다)은, 다음의 방법으로 행해집니다.
static const를 사용하는 것은 코드의 다른 const 변수를 사용하는 것과 같습니다.즉, 컴파일 전 프로세스에서 코드 내에서 단순히 치환되는 #define이 아니라 정보의 출처를 추적할 수 있습니다.
다음 질문에 대해서는 C++ FAQ Lite를 참조해 주십시오.http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7
- 정적 Const가 입력되며(유형이 있음), 유효성, 재정의 등이 컴파일러에 의해 확인될 수 있습니다.
- #defined는 정의되지 않은 상태로 재지정할 수 있습니다.
보통 정적 Constatic을 사용하는 것이 좋습니다.단점은 없습니다.프리 프로세서는 주로 조건부 컴파일에 사용해야 합니다(때로는 매우 지저분한 트릭에 사용되기도 합니다).
클래스의 모든 인스턴스 간에 공유할 상수를 정의하는 경우 static const를 사용합니다.상수가 각 인스턴스에 고유할 경우 const를 사용합니다(단, 클래스의 모든 컨스트럭터는 초기화 목록에서 이 const 멤버 변수를 초기화해야 합니다).
언급URL : https://stackoverflow.com/questions/1637332/static-const-vs-define
'programing' 카테고리의 다른 글
앱을 렌더링할 때 firestore에서 컬렉션을 가져와 vuex 상태로 설정하는 방법은 무엇입니까? (0) | 2022.08.27 |
---|---|
부호 없는 인덱스를 사용하여 역방향 'for' 루프를 수행하는 가장 좋은 방법은 무엇입니까? (0) | 2022.08.27 |
함수 포인터의 역참조는 어떻게 이루어집니까? (0) | 2022.08.27 |
C 프리프로세서를 사용하여 문자열에 int 연결 (0) | 2022.08.27 |
FD_CLOEXEC fcntl() 플래그의 기능은 무엇입니까? (0) | 2022.08.27 |