2014-11-05 5 views
6

저는 항상 C++을 가장 강력하게 유형화 된 언어로 간주했습니다.
그래서 나는 꽤 에 충격을 받았다.Table 3 of this paper은 C++이 약하게 입력 된 것을 볼 수있다.C++은 약한 타입으로 간주됩니까? 왜?

분명히, 캐스팅을 입력으로 인해 C 및 C++ 약하게하기 때문에 입력 된 것으로 간주된다

, 하나는 포인터로 정수이었다 구조의 필드를 해석 할 수 있습니다.

중요한 것은 모두 유형 캐스팅의 존재입니까? 그러한 캐스트의 명백 함이 중요하지 않습니까?

더 일반적으로 C++이 약하게 입력된다는 사실이 일반적으로 받아 들여지고 있습니까? 왜?

+1

혹시 하스켈에서 프로그래밍을한다면, C++가 실제로 약하게 입력 된 방법을 배우게됩니다! ;-) – Claudix

+2

C++은 약하게 타입이 지정되어 있지 않지만 원하는 경우 타입 시스템을 파괴 할 수 있습니다. 그래서 완전히 강하게 타이핑되지는 않았다고 주장 할 수 있습니다. – juanchopanza

+0

.. 그리고 당신이 허용한다면 (형벌은 까다 롭습니다) –

답변

16

그 종이 첫 번째 주장 : 대조적으로

는 언어 유형 혼란이 자동으로 (들키지)가 발생할 수있는 경우에 약한 타입, 결국 지역화하기 어려운 오류가 발생할 수 있습니다.

그리고 주장 :

는 또한, C 및 C++ 고려 약하게하기 때문에 입력되어, 캐스팅을 입력하기 때문에, 하나는 포인터로 정수이었다 구조의 필드를 해석 할 수 있습니다.

이것은 내게 모순처럼 보입니다. C 및 C++에서 캐스트의 결과로 발생할 수있는 유형 혼란은 자동으로 발생하지 않습니다. 캐스트가 있습니다! 이것은 그 언어의 어느 쪽이든이 약식 형인 것을 보여주지는 않습니다. 적어도 그 논문의 정의에 의해서가 아닙니다. 즉, 논문의 정의에 따르면, C 및 C++ 일 수있다.은 아직도 약한 타입으로 간주된다. 이미 질문에 대한 설명에 언급 된 것처럼 언어가 암시 적 유형 변환을 지원하는 경우가 있습니다. 많은 유형을 암시 적으로 bool으로 변환 할 수 있습니다. int의 문자 0은 자동으로 모든 포인터 유형으로 변환 될 수 있으며, 다양한 크기의 정수 사이의 변환 등이있을 수 있으므로 C 및 C++ 약식 유형을 고려해야합니다. 논문의 목적을 위해. 종이의 목적

int main() { 
    int i = 0; 
    void *v = &i; 
    char *c = v; 
    return *c; 
} 

, 확실히 약한 입력 고려해야합니다

C (그러나 C++)에 대한

도 언급 할 가치가 더 위험 암시 적 변환이 있습니다. 비트의 재 해석은 조용히 발생하며 일반적으로 관련없는 유형을 사용하도록 수정하여 훨씬 더 악화 될 수 있습니다. 정의되지 않은 동작은 일반적으로 비트를 재 해석하는 것과 동일한 효과가 있지만 정의가 활성화되면 신기하지만 때로는 재미있는 방식으로 불어납니다 .

일반적으로 "강하게 입력 된"및 "약하게 입력 된"고정 된 정의가 없다고 생각합니다. 다양한 등급이 있습니다. 어셈블리와 비교하여 강력한 형식의 언어는 파스칼에 비해 약하게 입력 될 수 있습니다. C 또는 C++이 약 유형인지 여부를 판별하려면, 약한 유형이 원하는 것이 무엇인지를 먼저 물어야합니다.

+0

+1 멋진 점.그러나 질문에 대답하기 위해 C++이 허용 된 정의가 무엇이든 강력하게 형식화되었는지 여부도 언급해야합니다. – Mehrdad

+1

+1 좋은 잡기 wrt 모순! –

+1

@Mehrdad 동의하고 내 대답을 확장했습니다. – hvd

5

"weak typed"은 상당히 주관적인 용어입니다. 나는 "정적으로 입력 된""엄격한 타입"용어들이 단어를 더 객관적이고 더 정확하기 때문에, "동적으로 입력" "느슨한 타입"선호합니다.

내가 알 수있는 것에서 사람들은 일반적으로 "weakly typed"를 "이 언어의 유형 개념을 좋아하지 않는다"는 작은 의미의 용어로 사용합니다. 특정 언어에 대한 전문적 또는 기술적 논쟁을 제기 할 수없는 사람들을위한 일종의 논쟁 광고 hominem (또는 오히려, 인자 광고 linguam)입니다.

"엄격하게 형식화 된"이라는 용어도 약간 다른 해석을 사용합니다. 내 경험상 일반적으로 받아 들여지는 의미는 "유형이 일치하지 않으면 컴파일러에서 오류가 발생합니다"입니다. 또 다른 해석은 "암시 적 변환이 없거나 거의 없습니다"입니다. 이것에 기반하여 C++은 실제로 엄격하게 유형화 된 언어로 간주 될 수 있으며 대부분의 경우 해당 언어로 간주됩니다. 나는 C++에 관한 일반적인 합의가 이라는 것이 엄격히 유형화 된 언어라고 말하고 싶습니다.

물론 우리는 질문에 대한보다 뉘앙스가있는 접근 방식을 시도 할 수 있으며 언어의 일부가 엄격하게 입력되고 (대다수의 경우) 나머지 부분은 느슨하게 입력됩니다 (암시 적 변환, 예 : 산술 변환 네 가지 유형의 명시 적 변환).

또한 몇 가지 언어에 익숙하지 않은 프로그래머, "엄격한"과 "정적", "느슨한"및 "느슨한"을 구분할 수 없거나 만들 수없는 초보자도 있습니다. "역동적 인"두 가지 - 그렇지 않으면 직각 - 개념 제한된 경험을 기반으로 (일반적으로 예를 들어, 인기있는 스크립트 언어에서 역 동성과 느슨한 타이핑의 상관 관계)를 기반으로합니다.

실제로 C++ (가상 호출) 부분은 유형 시스템이 부분적으로 동적이어야한다는 요구 사항을 부과하지만 표준의 다른 것들은 엄격해야합니다. 이것도 직각 개념이므로 문제는 아닙니다.

요약 : 아마도 언어가 이고 어떤 언어 나 다른 언어로 완벽하게 일 수는 있지만 특정 언어의 특정 속성이 지배적이라고 말할 수 있습니다. C++에서는 엄격함이 확실히 독점합니다.

0

는 대조적으로, 언어는 형식 혼란이 자동으로 (들키지)가 발생할 수있는 경우에 약한 타입, 결국 지역화하기 어려운 오류가 발생할 수 있습니다.

음, 예를 들어, C++에서 일어날 수있다 : 하나는 필드를 해석 할 수있는,

#define _USE_MATH_DEFINES 
#include <iostream> 
#include <cmath> 
#include <limits> 

void f(char n) { std::cout << "f(char)\n"; } 
void f(int n) { std::cout << "f(int)\n"; } 
void g(int n) { std::cout << "f(int)\n"; } 

int main() 
{ 
    float fl = M_PI; // silent conversion to float may lose precision 

    f(8 + '0'); // potentially unintended treatment as int 

    unsigned n = std::numeric_limits<unsigned>::max(); 
    g(n); // potentially unintended treatment as int 
} 
또한

, C 및 C++ 약하게 입력 캐스팅으로 인해, 이후 입력 된 것으로 간주된다 구조체는 포인터로 정수였습니다.

음 ... 암묵적인 변환을 통하지 않으므로 어리석은 논증입니다. C++은 타입 간의 명시 적 형변환을 허용하지만 이는 거의 "약"하지 않습니다. 위의 사이트 자체 정의에서 요구하는대로 실수로/자동으로 발생하는 것은 아닙니다.

중요하게 유형 캐스팅이 있습니까? 그러한 캐스트의 명백 함이 중요하지 않습니까?

Explositness는 중요한 고려 사항입니다. 프로그래머가 컴파일러의 유형에 대한 지식을 무시하도록하는 것은 C++의 "강력한"기능 중 하나이며 약점이 아닙니다. 실수로 사용하는 경향이 없습니다.

더 일반적으로 C++이 약하게 입력된다는 사실이 일반적으로 받아 들여지고 있습니까? 왜?

아니요 - 받아 들일 수 없다고 생각합니다. C++은 비교적 강력하게 형식화되었으며, 역사적으로 문제를 일으킨 관대 한 방법은 void*에서 다른 포인터 유형으로의 암시 적 캐스트와 캐스팅 연산자 및 생성자 explicit의 세부적인 제어와 같이 다시 정리되었습니다.

-2

내가 당신에게 간단한 예를 들어 보겠습니다 :

if (a + b) 

C는/C + = 부울에 int로 플로트에서 암시 적 변환을 할 수 있습니다.

강력한 형식의 언어는 이러한 암시 적 변환을 허용하지 않습니다.