c++11constexpr 사용 시 발생하는 구덩이 상세 정보
다음 예제는 다음과 같습니다.
#include <iostream>
constexpr int n = 10;
constexpr char *msg = "Hello, world!";
int main()
{
for (auto i = 0; i < n; ++i) {
std::cout << msg << std::endl;
}
}
constexpr은 모두에게 익숙한 것일 뿐만 아니라, 가장 자주 사용하는 c++11의 새로운 특성 중의 하나이기도 하다.매크로에 비해 더 강한 유형의 안전을 제외하고constexpr는 컴파일러 계산을 가져왔다.위의 코드는 상당히 간단합니다. "Hello, world!"를 순환 출력합니다.이 문자열은 10번입니다.
이렇게 간단한 코드에 대해 토론할 필요가 있습니까?처음에 나도 이렇게 생각했지만, 우리가 컴파일해서 실행할 때 다음과 같은 경고를 받게 된다.
$ g++ --version
g++ (GCC) 10.2.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ -std=c++17 -Wall -Wextra test.cpp
test.cpp:4:23: : ISO C++ forbids converting a string constant to ‘char*' [-Wwrite-strings]
4 | constexpr char *msg = "Hello, world!";
| ^~~~~~~~~~~~~~~
이 정보는 c++가char*에 문자열 글자의 값을 부여하는 것을 허락하지 않는다는 것을 의미합니다.하지만constexpr에 대해선문서
A constexpr specifier used in an object declaration implies const.
여기의object는 변수로 이해할 수 있습니다. 이것은 constexpr가 수식한 변수는 은밀하게 const 한정자를 추가한다는 뜻입니다.
즉,
// T
constexpr T a = xxx;
// , :
T const a = xxx;
우리가 있는 이곳의 T는 실제로 지침을 포함하여 임의의 유형을 채울 수 있다.이것은 우리의 바늘 변수에 const가 있다는 것을 설명하는 것이 아닙니까?눈치 빠른 독자들은 아마도 답을 알고 있을 것이다. constexpr에 추가된 것은 맨 윗부분의 const이다.
그래서 우리의 코드는 실제로 이렇다.
//
constexpr char *msg = "Hello, world!";
//
char * const msg = "Hello, world!";
다음 줄의 msg는 실제적으로char를 가리키는 바늘 상수이며, 우리는 그것을 통해 가리키는 문자열을 임의로 수정할 수 있다. (물론 이것은 정의되지 않은 행위이다.)바늘 상량은 우리가 이 바늘을 다른 대상을 다시 가리킬 수 없다는 것을 의미한다. 이const는 바늘 자체에 작용하기 때문에 맨 윗부분const라고 부른다.한편, 문자열 상수의 유형은constchar[N]입니다. 표현식에서constchar*로 퇴화됩니다. 이것은 상수 문자열을 가리키는 바늘을 나타냅니다. 여기의const의 밑바닥은 우리의 바늘 자체가 아니라 가리키는 대상에 작용하기 때문입니다.
맨 윗부분const에 대해 값을 부여할 때 제거할 수 있지만 밑부분const는 안 됩니다. 이것이 컴파일러가 경고를 보내는 이유입니다.
정확한 방법도 간단합니다. constexpr은 const의 등가 대체품이 아닙니다. 맨 윗부분만 추가할 뿐 밑부분만 추가할 수 있습니다.
그래서 constexpr의 문자열 상수는 이렇게 써야 합니다.
constexpr const char *p = "Hello, world!";
또는 당신의 컴파일 환경은 c++17을 지원합니다. 저는 당신이 이렇게 쓰는 것을 추천합니다.
#include <string_view>
constexpr std::string_view msg = "Hello, world!";
string_ 사용view 이후에는 위의 맨 윗층/밑층const의 구덩이가 나타나지 않습니다.그래서 현대 c++에서는 나체 바늘을 사용하지 않아도 되도록 사용하지 않는다.참고
https://stackoverflow.com/questions/54258241/warning-iso-c-forbids-converting-a-string-constant-to-char-for-a-static-c
총결산
c++11 constexpr를 사용할 때 구덩이를 만났을 때 이 글을 소개합니다. 더 많은 c++ 11 constexpr 구덩이 내용은 저희 이전의 글을 검색하거나 아래의 관련 글을 계속 훑어보십시오. 앞으로 많은 응원 부탁드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
C++11 thread 호출 객체의 구성원 함수참고 자료https://segmentfault.com/q/1010000009379779/a-1020000009380112std::thread 호출 클래스의 구성원 함수는 클래스의 대상 포인터를 매개 변수로 전달해야 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.