2010-07-21 9 views
9

ANSI C 컴파일러는 해당 매개 변수에 const 한정자가없는 함수 호출에서 문자열 리터럴 인수를 플래그로 사용하지 않는 이유는 무엇입니까? 예를 들어 다음 코드는 읽기 전용 메모리에 쓰기를 시도하여 예외를 생성 할 수 있습니다.문자열 리터럴 대 const char * in C

void somefunc(char buffer[10]); 

void somefunc(char buffer[10]) { 
    int i; 

    for (i = 0; i < 10; i++) 
     buffer[i] = 0; 
} 

int main(int argc, char **argv) { 

    somefunc("Literal"); 
    return 0; 
} 

이 상황은 컴파일 할 때 확인할 수 있지만 VS2010 및 gcc에서는 나타나지 않습니다. const char * 인수로 somefunc를 호출하면 컴파일러 경고가 생성됩니다.

+0

좋은 질문 - gcc는'-Wextra '를 사용하더라도 이것을 포착하지 않습니다. –

+0

함수를 선언 한 후 다음 줄을 정의하는 것은 무엇입니까? :) – GManNickG

+0

Hans : 질문을 수정하여 ANSI C를 지정했습니다. 어쨌든 컴파일러 오류가 발생했다고 제안하지 않았습니다. 레벨 3 또는 4 경고는 단순히 잠재적으로 위험한 상황을 강조 표시합니다. – Robin

답변

11

GCC : 플래그를 -Wwrite-strings

PS를 사용합니다. gcc 매뉴얼은 왜 이것이 -Wall의 일부가 아닌지 설명합니다. 어쨌든 항상 그렇듯이 특정 요구 사항과 코딩 스타일에 맞는 -W 플래그 조합을 찾아야합니다. 예를 들어, 최근의 프로젝트에서 나는 이런 식으로 뭔가를 사용했다 : -Werror -Wall -Wextra -Wformat=2 -Winit-self -Wswitch-enum -Wstrict-aliasing=2 -Wundef -Wshadow -Wpointer-arith -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wdisabled-optimization -Wunused-macros -Wno-unused

6

문자열 리터럴은 C에서 const가 아닙니다. C++에서는 그렇습니다.

편집 : 내 의견에 대해 혼동을 없애기 위해 실제로 유형을 변경하는 것이 아니라 유형을 언급하고 있습니다.

+1

당신은 그걸 어떻게 생각하니? –

+2

@Paul, 그는 맞습니다. C99 §6.4.5/5 : "문자 스트링 리터럴의 경우, 배열 요소는'char' 타입을가집니다. 문자열 리터럴을 수정하는 것은 정의되어 있지 않지만, 요소 타입은'const char'가 아니라'char'입니다. –

+0

@Matthew : 설명 해 주셔서 고마워요. "const"를 "읽기 전용"으로 해석했습니다. 물론 문자열 리터럴은 대개 C 또는 C++로되어 있습니다. 그러나 문자열의 실제 * 유형 * 리터럴. –

15

레거시 K &입니다. 그것을 고치면 백만 가지 프로그램이 깨질 것입니다.

7

한스 패전트가 말한 내용. const는 1989 년에 ANSI 표준의 일부로 추가 되었기 때문에 이전에는 const가 없었습니다.

+1

@Georg : const 키워드가 ANSI C에 추가되었으므로 constant로 문자열 리터럴을 갱신하기에는 이미 너무 늦었습니다. – ninjalj

+0

아, 지금 내가 널 데려 간다. –

4

GNU 컴파일러 (물론 인텔 C 컴파일러, IIRC) 경고를 방출합니다, -Wwrite-string를 사용하는 경우 :

$ gcc -Wall -Wwrite-strings -o foo /tmp/foo.c 
/tmp/foo.c: In function 'main': 
/tmp/foo.c:12: warning: passing argument 1 of 'somefunc' discards qualifiers from pointer target type 
/tmp/foo.c:3: note: expected 'char *' but argument is of type 'const char *' 

VS2010에 관해서는 당신을 도울 수 없습니다.

+1

쿨 - 왜'-Wwrite-strings'가'-Wall' 또는'-Wextra'에도 포함되지 않는지 궁금합니다. –