[c] C의 절대 값 함수가 const 입력을 허용하지 않는 이유는 무엇입니까?

C에서, 절대 값 함수 (float를 받아들이는)의 프로토 타입은

 float fabsf( float );

이 프로토 타입이 다음과 같은 상수 값을 허용하지 않는 이유는 무엇입니까?

 float fabsf( float const );

fabsf는 입력 값을 변경하지 않습니까?

입력을 받아들이고 fabsf를 ​​호출하는 함수가 있으면 입력을 const로 지정하지 않아야합니까?

이 상황에서 const 정확성을 처리하는 적절한 방법은 무엇입니까?



답변

편집하다

MM이 언급했듯이 프로토 타입 의 매개 변수에 const대해서는 무시됩니다. 원본 답변의 수정 된 출처 (아래 참조)는 다음과 같습니다.

float correct(float const value);

float erroneous(float const value);

float changer(float value);

float correct(float value) {
  return -value;
}

float erroneous(float value) {
  value = -value;
  return value;
}

float changer(float value) {
    value = -value;
    return value;
}

오류 메시지가 없습니다.

어쨌든, 나는 그것이 도움이되기를 바라면서 원본을 그대로 두겠습니다.


기발한

const매개 변수에서이 만드는 매개 변수 읽기 전용 함수 내에서합니다.

예를 들면 다음과 같습니다.

float correct(float const value) {
  return -value;
}

float erroneous(float const value) {
  value = -value;
  return value;
}

float changer(float value) {
  value = -value;
  return value;
}

이 소스는 오류 메시지없이 컴파일되지 않습니다.

함수 correct()는 주어진 값을 읽고 부호를 변경하고 부정 된 값을 반환합니다.

erroneous()매개 변수에 할당이 있다는 점을 제외하고는 함수 가 효과적으로 동일한 것으로 보입니다. 그러나 매개 변수는 const허용되지 않습니다.

다음으로 함수 changer()는 이전과 같이 작동하지만 오류는 없습니다.

콜 사이트를 보자 :

float f = 3.14159;
float g = correct(f); // or erroneous(f) or changer(f)

변수 f인수로 제공이됩니다 복사 매개 변수로 value. changer()호출 되더라도 변경되지 않습니다 .

매개 변수를 일종의 로컬 변수로 보려고 할 수 있습니다. 실제로 이들은 생성 된 머신 코드에서 대부분 이와 같이 처리됩니다.


const가끔 봅니까? 포인터 가 매개 변수로 정의 된 경우이를 볼 수 있습니다 .

지정된 값 을 변경 하지 않으려면 추가해야합니다 const. 그러나 올바른 위치에서 수행하십시오!

void effective(int const * pointer);

void futile(int * const pointer);

void possible_but_overly_restricted(int const * const pointer);


답변

C는 값으로 전달을 사용합니다. 함수의 매개 변수 값은 사용자가 제공 한 인수의 사본입니다.

const와 non-const float를 모두 복사해도 괜찮으며 결과는 non-const float입니다.

과제와 비슷합니다 :

const float f = 5.5f;
float g = f;   // OK

실제로이 언어는 식의 값을 절대로 사용할 수 없도록 지정합니다. const즉, 변수에서 값을 읽을 때 해당 값은 const변수가 아니더라도 해당 값이 아닙니다 .


답변

C 언어에서 사용하는 값의 의미를 통과하기 때문에, 어떤 내부적으로 수정 될 수 있지만 당신이 그것을에 전달한다는 주장은, 직접이 전달 값에 영향을주지 않습니다.

이 그 발신자의 관점에서 수단 float fabsf( float );float fabsf( const float );동일합니다. 따라서 매개 변수를 만들 필요는 없습니다 const.

그것은 어디 않습니다 메이크업 센스를 사용하는 const당신이 전달 매개 변수, 예를 들면 포인터 인 경우 :

void print_string(char *str)

이 함수는 이름에서 제안한 내용에도 불구하고 주어진 포인터를 역 참조하고 그 점을 수정 str[0] = 'x'하여 호출 함수가 볼 수있는 변경을 초래할 수 있습니다. 이 함수가 다음과 같이 정의 된 경우 :

void print_string(const char *str)

호출자는 함수가 지시하는 내용을 수정할 수 없도록 보장 str됩니다.


답변

언어 변호사 관점을 추가하려면 다음을 수행하십시오.

두 가지 기능 유형이 호환 되려면 둘 다 호환 가능한 반환 유형을 지정해야합니다. 또한, 매개 변수 유형 목록은 둘 다 존재하는 경우 매개 변수의 수와 줄임표 종결자를 사용하는 데 동의해야합니다. 해당 매개 변수는 호환 가능한 유형을 가져야합니다 . [..] 형식 호환성 및 복합 형식의 결정에서 [..] 정규화 된 형식으로 선언 된매개 변수는 선언 된 형식의 정규화되지 않은 버전을 갖는 것으로 간주됩니다 .

N1570 6.7.6.3/15

이는이 두 가지가 호환됨을 의미합니다.

void foo(int const);
void foo(int);

따라서 함수 내에서 (복사-값으로 호출!) 매개 변수를 실수로 수정하지 않으려는 경우 프로토 타입을 작성하거나 사용하지 않고 const(더 의미가없고 의미가 적고 입력 / 읽기가 적음) const함수 정의에 추가 할 수 있습니다 . 신체.


답변