C에서 'char**'를 'const char* const*'로 변환할 수 없는 이유는 무엇입니까?
다음 코드 스니펫은 (올바르게) C에서 경고 및 C++에서 오류를 나타내고 있습니다(각각 버전 3.4.5 및 4.2.1에서 테스트된 gcc 및 g++를 사용).MSVC는 신경 쓰지 않는 것 같습니다).
char **a;
const char** b = a;
을 사용하다
이 문제에 대한 C++ 해결책은 b를 const char * const * 로 변경하는 것입니다.이것에 의해, 포인터의 재할당이 허가되지 않고, const-correctness(C++ FAQ)를 회피할 수 없게 됩니다.
char **a;
const char* const* b = a;
그러나 순수 C에서는 수정판(const char * const * const * 를 사용)이 아직 경고하고 있기 때문에 그 이유를 알 수 없습니다.깁스를 하지 않고 이 문제를 해결할 수 있는 방법이 있을까요?
다음 중 하나:
1) C'에 경고가 입니까?C++는 C++는 C++는 C++를 사용합니다.
이 입니까? ( char**는 이 char**를 가리킵니다(또한 컴파일러에 의해 강제됩니다).예를 들어 함수를 작성하려면 다음과 같이 입력합니다.
void f(const char* const* in) {
// Only reads the data from in, does not write to it
}
char***로 호출하고 싶은데 파라미터의 올바른 타입은 무엇입니까?
나는 몇 년 전에 같은 문제가 있었고 그것은 나를 끝없이 짜증나게 했다.
은 좀 더 C를 하는 등의 되어 있지 않습니다).char**
로로 합니다.const char*const*
결과적으로, 그것은 허용되지 않습니다.C++ 규격에서는 이와 같은 경우를 허용하는 규칙이 더 많이 포함되었습니다.
결국, 그것은 단지 C 기준의 문제일 뿐이다.다음 표준(또는 기술 보고서)에서 이 문제를 다루었으면 합니다.
그러나 순수 C에서는 이것이 여전히 경고를 주고 있으며, 나는 왜 그런지 이해할 수긍정적이다.
이치노'일정하다는 '일정하다'를 하고 '일정하다'는 것을 const_cast
제거 'C'const
할 수 없습니다.const
이러한 Const 포인터 또는 참조를 통해 오브젝트를 만듭니다.
「」의 값const
-정확성 --const
프로그래머 오류를 검출하는 것이 대부분입니다.라고 const
안 할 수 사람'이 있어야 한다고 또는 적어도 접근권을 가진 사용자에게는const
버전만 변경할 수 없습니다.★★★★★★★★★★★★★★★★★★:
void foo(const int*);
한 대로, 「 」foo
에는 인수가 가리키는 정수를 수정할 권한이 없습니다.
가 왜const
HappyDude 뿐이죠 니다다 - - - - - - - - - - - - - 。음음 츠키해피듀드입니다.
char *y;
char **a = &y; // a points to y
const char **b = a; // now b also points to y
// const protection has been violated, because:
const char x = 42; // x must never be modified
*b = &x; // the type of *b is const char *, so set it
// with &x which is const char* ..
// .. so y is set to &x... oops;
*y = 43; // y == &x... so attempting to modify const
// variable. oops! undefined behavior!
cout << x << endl;
(非)const
으로 변환할 수 있는 은 const const를 .const
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
에 선언된 오브젝트const
특히 특별합니다.컴파일러는 절대 변하지 않는다고 가정할 수 있습니다. 「」의 경우는, 「」입니다.b
을 할 수 a
되면 될 수 .const
할 수 없게 최적화도 .이렇게 하면 컴파일러에 의뢰한 체크가 무효가 되어 변수 값을 변경할 수 없게 됩니다.컴파일러 최적화도 무효가 됩니다.
, 합니다.42
에서는, 「」43
기타 프로그램은 크래시 됩니다.
편집 추가:
HappyDude:이치노C는 C langauge를 합니다.const char * const *
C++ 언어와는 근본적으로 다릅니다.이 소스 라인에 대해서만 컴파일러 경고를 소거하는 것을 고려해 주십시오.
호환성이 있다고 간주되기 위해서는 소스 포인터가 직전의 간접 레벨로 일정해야 합니다.그러면 GCC에서 다음과 같은 경고가 표시됩니다.
char **a;
const char* const* b = a;
하지만 이것은 아니다:
const char **a;
const char* const* b = a;
또는 다음과 같이 캐스팅할 수 있습니다.
char **a;
const char* const* b = (const char **)a;
f() 함수를 호출하려면 앞서 말한 것과 동일한 캐스트가 필요합니다.이 경우 암묵적인 변환을 할 수 있는 방법은 없는 것으로 알고 있습니다(C++ 제외).
번거롭지만 다른 수준의 리다이렉션을 추가할 경우 다음 작업을 수행하여 포인터에 푸시 다운할 수 있습니다.
char c = 'c';
char *p = &c;
char **a = &p;
const char *bi = *a;
const char * const * b = &bi;
약간 다른 의미이지만, 보통은 사용할 수 있고 깁스를 사용하지 않습니다.
적어도 MSVC 14(VS2k5)와 g++ 3.3.3에서는 const char * const *에 char**를 암묵적으로 캐스팅할 때 오류가 발생하지 않습니다.GCC 3.3은 경고를 발행합니다만, 이것이 올바른 것인지 잘 모르겠습니다.
test.c:
#include <stdlib.h>
#include <stdio.h>
void foo(const char * const * bar)
{
printf("bar %s null\n", bar ? "is not" : "is");
}
int main(int argc, char **argv)
{
char **x = NULL;
const char* const*y = x;
foo(x);
foo(y);
return 0;
}
C 코드로 컴파일을 사용한 출력: cl /TC / W4 / Wp64 test.c
test.c(8) : warning C4100: 'argv' : unreferenced formal parameter
test.c(8) : warning C4100: 'argc' : unreferenced formal parameter
C++ 코드로서 컴파일을 사용한 출력: cl /TP / W4 / Wp64 test.c
test.c(8) : warning C4100: 'argv' : unreferenced formal parameter
test.c(8) : warning C4100: 'argc' : unreferenced formal parameter
gcc에서의 출력: gcc - Wall test.c
test2.c: In function `main':
test2.c:11: warning: initialization from incompatible pointer type
test2.c:12: warning: passing arg 1 of `foo' from incompatible pointer type
g++: g++-Wall 테스트에서의 출력.c
출력 없음
const 키워드는 데이터를 변경할 수 없거나 일정하지 않다는 것을 의미하지는 않지만 읽기 전용으로 취급됩니다.다음 사항을 고려하십시오.
const volatile int *const serial_port = SERIAL_PORT;
유효한 코드입니다.어떻게 휘발성과 지속성이 공존할 수 있을까요?간단하죠.volatile은 데이터를 사용할 때 항상 메모리를 읽도록 컴파일러에 지시하고 serial_port 포인터를 사용하여 메모리에 쓰려고 하면 오류를 생성하도록 컴파일러에 지시합니다.
const는 컴파일러의 최적화에 도움이 됩니까?아니. 전혀 아니야.constness는 캐스팅을 통해 데이터에 추가 및 제거될 수 있기 때문에 컴파일러는 const 데이터가 실제로 일정한지 여부를 확인할 수 없습니다(다른 변환 단위로 캐스트를 수행할 수 있기 때문입니다).C++ 에서는, 문제를 한층 더 복잡하게 하기 위해서, 가변 키워드를 사용할 수도 있습니다.
char *const p = (char *) 0xb000;
//error: p = (char *) 0xc000;
char **q = (char **)&p;
*q = (char *)0xc000; // p is now 0xc000
읽기 전용 메모리(ROM 등)에 쓰려고 하면, 표준에서는 전혀 정의되어 있지 않습니다.
언급URL : https://stackoverflow.com/questions/78125/why-cant-i-convert-char-to-a-const-char-const-in-c
'programing' 카테고리의 다른 글
각각에 대해 내부에서 vue 데이터 개체에 액세스합니다. (0) | 2022.07.02 |
---|---|
Vue.js를 사용하여 프로펠을 변경한 후 편집 가능한 div의 캐럿 위치 (0) | 2022.07.02 |
Task.Factory.StartNew 대 새 작업 (0) | 2021.01.15 |
왜 인라인 소스 맵입니까? (0) | 2021.01.15 |
$ this에 대한 동적 참조는 작동하지 않지만 작동합니다. (0) | 2021.01.15 |