const char* 어레이 초기화 쉼표가 없는 경우 컴파일러 경고 생성
나는 C 코드에 문자열 리터럴 테이블을 많이 사용하고 있다.이 표들은 모두 이와 거의 비슷해 보인다.
static const char* const stateNames[STATE_AMOUNT] =
{
"Init state",
"Run state",
"Pause state",
"Error state",
};
위 코드의 문제는 테이블이 길어져서 개발 중에 변형되면 나는 가끔 쉼표를 잊어버린다.코드는 쉼표가 누락되어도 문제없이 컴파일되지만, 내 프로그램은 마지막 문자열이 설정되면서 다운된다.NULL
나는 검증하기 위해 민GW와 케이일 컴파일러를 이용했다.
쉼표가 없는 경우 초기화를 위해 컴파일러 경고를 생성할 수 있는 방법이 있는가?
포장 간격const char*
괄호 쌍에서 다음 조각에 표시된 것처럼 문제를 해결해야 한다.
static const char* const stateNames[5] =
{
("Init state"),
("Run state"),
("Pause state") //comma missing
("Pause state3"),
("Error state")
};
쉼표를 잊어버린 경우 다음과 유사한 컴파일 오류가 발생한다.error: called object is not a function or function pointer
쉼표를 잊어버린 경우 실제로 C가 다음 쉼표 또는 배열이 끝날 때까지 두 개 이상의 문자열을 연결한다는 점에 유의하십시오.예를 들어, 다음과 같이 쉼표를 잊었다고 하자.
static const char* const stateNames[] =
{
"Init state",
"Run state",
"Pause state" //comma missing
"Pause state3" //comma missing
"Error state"
};
int main(void)
{
printf("%s\n", stateNames[0]);
return 0;
}
생성되는 코드는 다음과 같다(다른 컴파일러는 유사한 코드를 생성함).
.LC0:
.string "Init state"
.string "Run state"
.string "Pause statePause state3Error state" ; oooops look what happened
.quad .LC0
.quad .LC1
.quad .LC2
main:
push rbp
mov rbp, rsp
mov eax, OFFSET FLAT:.LC0
mov rdi, rax
call puts
mov eax, 0
pop rbp
ret
마지막 세 개의 문자열은 연결되고 배열은 예상 길이가 아닌 것이 분명하다.
컴파일러가 어레이를 카운트하도록 하고 예기치 않은 결과가 발생할 경우 오류 메시지를 생성하십시오.
enum { STATE_AMOUNT = 4 };
static const char* const stateNames[] =
{
"Init state",
"Run state",
"Pause state" // <--- missing comma
"Error state",
};
_Static_assert( sizeof stateNames / sizeof *stateNames == STATE_AMOUNT,
"oops, missed a comma" );
구현할 아이디어는 이 스레드를 참조하십시오._Static_assert
컴파일러가 매우 오래되어 이를 지원하지 않는 경우.
추가적으로, 이것은 또한 당신이 새로운 상태를 추가하지만 문자열 테이블을 업데이트하는 것을 잊었을 때 도움이 될 수 있다.하지만 여러분은 X 매크로를 들여다보는 것도 원할 것이다.
이 문제를 해결하기 위해 항상 명시적으로 크기가 지정된 어레이에 대한 참조를 사용해 왔다.
// no explicit size here
static const char* const stateNames[] =
{
"Init state",
"Run state",
"Pause state",
"Error state",
};
static const char* const (&stateNameVerifier)[STATE_AMOUNT] = stateNames;
http://coliru.stacked-crooked.com/a/593fc2eac80782a6
main.cpp:10:32: error: reference to type 'const char *const [5]' could not bind to an lvalue of type 'const char *const [4]'
static const char* const (&stateNameVerifier)[STATE_AMOUNT] = stateNames;
이것은 컴파일러가 여러분을 돕도록 하는 것이 아니지만, 나는 아래와 같이 글을 쓰면 인간이 쉼표를 남기지 않는 것이 더 쉽다는 것을 알게 되었다.
static const char* const stateNames[STATE_AMOUNT] =
{
"Init state"
, "Run state"
, "Pause state"
, "Error state"
};
'programing' 카테고리의 다른 글
Vite로 Vue2+Vuetify 앱을 빌드할 때 Vuetify 변수 재정의 (0) | 2022.04.14 |
---|---|
C 코드의 오류 처리 (0) | 2022.04.14 |
JPA @Column 주석을 참조하여 insertable=false 및 updateable=false에 대해 설명하십시오. (0) | 2022.04.14 |
드롭다운 목록에서 확인란을 선택한 후 v-자동 완성(복수) 검색 입력을 지우는 방법 (0) | 2022.04.14 |
Java: 날짜 생성자가 더 이상 사용되지 않는 이유와 내가 대신 사용하는 것은? (0) | 2022.04.13 |