programing

C에서 'char**'를 'const char* const*'로 변환할 수 없는 이유는 무엇입니까?

javaba 2022. 7. 2. 23:44
반응형

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

반응형