외부와 콘스탄트 혼합
내가 외측과 외측을 혼용할 수 있을까?만약 그렇다면, 순경 한정자는 그것이 선언된 범위 내에서만 그것의 통치를 강요하는가 아니면 그것이 선언된 번역 단위의 선언과 정확히 일치해야 하는가?즉, 다음과 같이 말할 수 있다.extern const int i;
심지어 실제 나는 항상이 아니고 그 반대일때도?
일반적인 패턴:
- file.h:
extern const int a_global_var;
- file.c:
#include "file.h"
const int a_global_var = /* some const expression */;
편집: 범례2k의 주석 삽입.고마워요.
C++17inline
변수들
만약 당신이 원한다고 생각한다면extern const
그러면 C++17 인라인 변수를 실제로 사용할 가능성이 더 높다.
이 놀라운 C++17 기능을 통해 다음을 실현하십시오.
- 각 상수에 대해 하나의 메모리 주소만 편리하게 사용
- 그것을 a로 저장하다.
constexpr
: Constexpr 외부 신고 방법? - 한 머리글에서 한 줄로 하다.
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
주체가 아닌hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
inline constexpr int notmain_i = 42;
const int* notmain_func();
#endif
notmain.cpp
#include "notmain.hpp"
const int* notmain_func() {
return ¬main_i;
}
컴파일 및 실행:
g++ -c -o notmain.o -std=c++17 -Wall -Wextra -pedantic notmain.cpp
g++ -c -o main.o -std=c++17 -Wall -Wextra -pedantic main.cpp
g++ -o main -std=c++17 -Wall -Wextra -pedantic main.o notmain.o
./main
참고 항목:인라인 변수는 어떻게 작동하는가?
인라인 변수의 C++ 표준
C++ 표준은 주소가 동일함을 보증한다.C++17 N4659 표준 초안 10.1.6 "인라인 지정자":
6 인라인 함수 또는 외부 연결이 있는 변수는 모든 변환 단위에서 동일한 주소를 가져야 한다.
cppreference https://en.cppreference.com/w/cpp/language/inline은 다음과 같이 설명한다.static
주어지지 않고, 그러면 그것은 외부적인 연계가 있다.
인라인 변수 구현
다음을 통해 구현 방법을 관찰할 수 있다.
nm main.o notmain.o
다음을 포함하는:
main.o:
U _GLOBAL_OFFSET_TABLE_
U _Z12notmain_funcv
0000000000000028 r _ZZ4mainE19__PRETTY_FUNCTION__
U __assert_fail
0000000000000000 T main
0000000000000000 u notmain_i
notmain.o:
0000000000000000 T _Z12notmain_funcv
0000000000000000 u notmain_i
그리고man nm
에 대해 말하다.u
:
"u" 기호는 고유한 글로벌 기호다.이것은 ELF 기호 바인딩의 표준 집합에 대한 GNU 확장이다.그러한 기호의 경우 동적 링커는 전체 프로세스에서 이 이름과 유형을 가진 기호가 하나만 사용되도록 할 것이다.
그래서 우리는 이것을 위한 ELF 전용 확장이 있다는 것을 알 수 있다.
C++ 17 이전:extern const
extern const
아래 예시와 같이 작동하지만, 에 대한 단점은 다음과 같다.inline
다음과 같다:
- 변수를 만드는 것은 불가능하다.
constexpr
이 기지로만inline
다음을 허용한다.외부 신고는 어떻게 하지? - 헤더와 cpp 파일에서 변수를 별도로 선언하고 정의해야 하므로 품위가 떨어진다.
main.cpp
#include <cassert>
#include "notmain.hpp"
int main() {
// Both files see the same memory address.
assert(¬main_i == notmain_func());
assert(notmain_i == 42);
}
notmain.cpp
#include "notmain.hpp"
const int notmain_i = 42;
const int* notmain_func() {
return ¬main_i;
}
주체가 아닌hpp
#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP
extern const int notmain_i;
const int* notmain_func();
#endif
C++17 이전 헤더만 사용할 수 있음
이것들이 더 좋은 것 같지는 않다.extern
솔루션, 그러나 단일 메모리 위치만 차지하며,
A constexpr
함수를 의미하기 때문에inline
모든 번역 장치에 정의가 나타나도록 허용(수정):
constexpr int shared_inline_constexpr() { return 42; }
제대로 된 컴파일러라면 호출에 줄을 서겠지
또한 a를 사용할 수 있다.const
또는constexpr
다음과 같은 정적 정수 변수:
#include <iostream>
struct MyClass {
static constexpr int i = 42;
};
int main() {
std::cout << MyClass::i << std::endl;
// undefined reference to `MyClass::i'
//std::cout << &MyClass::i << std::endl;
}
그러나 주소를 가져가는 등의 작업을 수행할 수 없으며, 그렇지 않으면 https://en.cppreference.com/w/cpp/language/static "Constant static members" 및 constexpr 정적 데이터 구성원 정의를 참조하십시오.
완전히 인라인으로 할 수 있는 방법은?
TODO: 메모리를 전혀 사용하지 않고 변수를 완전히 인라인으로 연결할 수 있는 방법이 없을까?
전처리가 하는 것과 비슷해
이 작업에는 어떻게든 다음과 같은 사항이 필요하다.
- 변수의 주소를 사용하는지 여부를 탐지하거나 금지
- 이 정보를 ELF 개체 파일에 추가하고 LTO가 이를 최적화하도록 하십시오.
관련:
Ubuntu 18.10, GCC 8.2.0에서 시험하였다.
그것들을 함께 사용할 수 있다.그러나 C++가 이름 장식을 할 때 기호 이름을 장식하는 데 사용되는 유형 정보에 항상 포함되기 때문에 항상성을 사용할 필요가 있다.그렇게extern const int i
와 다른 변수를 언급할 것이다.extern int i
외부 "C" {}을(를) 사용하지 않는 한, C 이름 장식은 const에 주의를 기울이지 않는다.
당신은 그것들을 함께 사용할 수 있고 당신은 항상 키워드를 무시하는 모든 종류의 일들을 할 수 있다. 왜냐하면 그것뿐이기 때문이다. 키워드.그것은 컴파일러에게 변수를 변경하지 않을 것이라고 말해 컴파일러가 유용한 선택을 할 수 있게 하고 의도하지 않았던 것들을 바꾸는 것을 멈추게 한다.
아마존닷컴은 좀 더 많은 배경을 가진 괜찮은 기사를 가지고 있다.
응, 같이 써도 돼.
만약 당신이 "external const in i"를 선언한다면, 나는 그것의 전체 범위를 넘어설 것이다.그것을 불변으로 재정의하는 것은 불가능하다.물론 const 플래그를 던져 버림으로써(const_cast 사용) 우회할 수 있다.
참조URL: https://stackoverflow.com/questions/2190919/mixing-extern-and-const
'Programing' 카테고리의 다른 글
Thread.current를 호출하는 이유캐치 인터럽트Exception 블록의 스레드.인터럽트()? (0) | 2022.05.16 |
---|---|
옵션이 개체 배열인 경우 vue-다중 선택 옵션을 미리 선택하는 방법 (0) | 2022.05.16 |
공리 호출에 성공한 후 Vue.js 구성 요소가 상위 구성 요소로 방출되지 않음 (0) | 2022.05.15 |
선행 0으로 Java 문자열을 포맷하는 방법 (0) | 2022.05.15 |
OpenGL 메서드만 사용하여 텍스트를 그리는 방법 (0) | 2022.05.15 |