수색…


리터럴 및 변수 비교

가치를 어떤 변수와 비교한다고 가정 해보자.

if ( i  == 2) //Bad-way
{
    doSomething;
}

이제 당신이 == = 와 착각했다고 가정 해 봅시다. 그렇다면 그것을 알아내는 데 당신의 달콤한 시간이 걸릴 것입니다.

if( 2 == i) //Good-way
{
    doSomething;
}

그런 다음 등호가 실수로 빠져 나면 컴파일러에서 "리터럴에 대한 할당 시도"에 대해 불평 할 것입니다. 두 변수를 비교할 때이를 보호하지는 않지만 약간의 도움이됩니다.

자세한 정보는 여기참조하십시오 .

함수의 매개 변수 목록을 비워 두지 마십시오. void를 사용하십시오.

호출 될 때 인자가 필요없는 함수를 생성하고 함수 프로토 타입과 함수 정의에서 매개 변수 목록을 정의하는 방법의 딜레마에 직면 해 있다고 가정합니다.

  • 프로토 타입과 정의 모두에 대해 매개 변수 목록을 비워 두는 선택권이 있습니다. 따라서 함수 호출 문과 같이 표시됩니다.

  • 당신은 어딘가에서 키워드 void 의 사용법 중 하나 (단지 몇 가지가 있음)를 읽었는데, 호출시 인수를 허용하지 않는 함수의 매개 변수 목록을 정의하는 것입니다. 그래서, 이것은 또한 선택입니다.

그렇다면 올바른 선택은 무엇입니까?

ANSWER : void 키워드 사용

일반 조언 : 특정 목적을 위해 사용할 특정 기능을 제공하는 언어는 코드에서 사용하는 것이 좋습니다. 예를 들어, #define 매크로 대신에 enum 사용하면 (다른 예가 #define ).

C11 절 6.7.6.3 "함수 선언자", 단락 10,

목록의 유일한 항목 인 void 유형의 이름이없는 매개 변수의 특별한 경우는 함수에 매개 변수가 없음을 지정합니다.

그 같은 절의 14 단락은 유일한 차이점을 보여줍니다 :

... 해당 함수의 정의의 일부인 함수 선언자의 빈 목록은 함수에 매개 변수가 없음을 지정합니다. 해당 함수 정의의 일부가 아닌 함수 선언자의 빈 목록은 매개 변수의 수 또는 유형에 대한 정보가 제공되지 않음을 지정합니다.

위의 내용에 대해 K & R (pgs- 72-73)이 제공 한 간략한 설명 :

또한 함수 선언에 인수가 포함되지 않은 경우
double atof(); 그것도 atof 의 주장에 대해 추측 할 것이 없다는 것을 의미한다. 모든 매개 변수 검사가 해제됩니다. 빈 인수 목록의이 특별한 의미는 구형 C 프로그램이 새 컴파일러로 컴파일되도록 허용하기위한 것입니다. 그러나 새로운 프로그램과 함께 사용하는 것은 나쁜 생각입니다. 함수가 인수를받는다면 선언하십시오. 인수가 없으면 void 사용합니다.

그래서 이것은 함수 프로토 타입이 어떻게 보일 것인가입니다 :

int foo(void);

그리고 이것은 함수 정의가 다음과 같아야합니다.

int foo(void)
{
    ...
    <statements>
    ...
    return 1;
}

위의 int foo() 유형의 선언 (즉, 키워드 void 를 사용하지 않고)을 사용하면 컴파일러가 foo(42) 와 같은 잘못된 명령문을 사용하여 함수를 호출하면 오류를 감지 할 수 있다는 장점이 있습니다. 이러한 종류의 함수 호출 문은 매개 변수 목록을 비워두면 오류를 발생시키지 않습니다. 오류는 조용히 지나가고 탐지되지 않으며 코드는 여전히 실행됩니다.

이것은 또한 다음과 같이 main() 함수를 정의해야한다는 것을 의미합니다 :

int main(void)
{
    ...
    <statements>
    ...
    return 0;
}

빈 매개 변수 목록으로 정의 된 함수는 인수를 사용하지 않지만 함수에 대한 프로토 타입을 제공하지 않으므로 함수가 인수를 사용하여 이후에 호출되면 컴파일러에서 불평하지 않습니다. 예 :

#include <stdio.h>

static void parameterless()
{
    printf("%s called\n", __func__);
}

int main(void)
{
    parameterless(3, "arguments", "provided");
    return 0;
}

그 코드가 proto79.c 파일에 저장되어 있다면 유닉스에서 GCC (데모 용으로 사용 된 macOS Sierra 10.12.5의 버전 7.1.0)로 컴파일 할 수 있습니다 :

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -pedantic proto79.c -o proto79
$

더 엄격한 옵션으로 컴파일하면 오류가 발생합니다.

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c:3:13: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
 static void parameterless()
             ^~~~~~~~~~~~~
proto79.c: In function ‘parameterless’:
proto79.c:3:13: error: old-style function definition [-Werror=old-style-definition]
cc1: all warnings being treated as errors
$

함수에 static void parameterless(void) 프로토 타입 static void parameterless(void) 를 지정하면 컴파일시 오류가 발생합니다.

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -pedantic proto79.c -o proto79 
proto79.c: In function ‘main’:
proto79.c:10:5: error: too many arguments to function ‘parameterless’
     parameterless(3, "arguments", "provided");
     ^~~~~~~~~~~~~
proto79.c:3:13: note: declared here
 static void parameterless(void)
             ^~~~~~~~~~~~~
$

도덕 - 항상 프로토 타입을 가지고 있는지 확인하고 규칙을 따르지 않을 때 컴파일러에서 알려주도록하십시오.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow