programing

C/C++ Best Practice(서명/부호 인트 및 함수 호출 포함)

abcjava 2023. 9. 13. 22:17
반응형

C/C++ Best Practice(서명/부호 인트 및 함수 호출 포함)

저는 C와 C++ 두 개의 다른 언어에 대해 이 질문을 합니다.

코드에서 요구하는 것과 반대의 정수 부호 기대를 가지는 함수를 호출할 때 가장 좋은 방법은 무엇입니까?

예를 들어,

uint32       _depth;                        // uint32 = DWORD
int          depth;

_BitScanForward(&_depth, (uint32)input);    // DWORD, DWORD
depth = (int)_depth;

_BitScanForward에 DWORD(unint32) 매개 변수가 필요합니다.변수가inputint16 타입으로 결과물을 처리해야합니다._depth내 코드의 int32로.

  1. 캐스팅에 신경을 써야 합니까?input보이는 대로?아마 컴파일러가 해줄 라는 건 알지만, 최선의 방법은 무엇인가요?
  2. 신고해도 되겠습니까?_depthint32로서 따라서 표시된 것처럼 나중에 주조할 필요가 없도록 해야 합니까?

참고:

컴플라이어에 대한 제 의견은 경험에 근거한 것입니다.VS에서 경고 없이 컴파일한 코드를 작성했지만 실행 시 충돌했습니다.알고 보니 제가 인코브 너비의 함수를 부른 겁니다그래서 저는 이 주제를 더 이상 컴파일러에게 맡기지 않습니다.

편집:

답이 도움이 됩니다. 감사합니다.제 질문을 좀 더 다듬겠습니다.만약 폭 문제가 없다면, 즉 함수가 전달되는 것보다 좁은 int를 기대하지 않는다면(분명히 실패할 것이다), 부호와 너비 차이를 처리하기 위해 컴파일러에 의존해도 괜찮을까요?

저는 당신이 선호하는 API와 일치하는 사용자 정의 래퍼 함수에 그 함수를 숨기는 것을 강력히 추천합니다(그리고 이 함수 내에서 적절한 명시적 주조를 함).컴파일러별 기능을 사용하는 경우, 래퍼 기능을 다시 구현하는 것만으로 다른 컴파일러로 포팅하는 것이 훨씬 쉬워진다는 추가적인 이점이 있습니다.

다음보다 좁은 정수형에서 명시적인 캐스트를 작성하는 것이 매우 중요합니다.int동일한 너비 또는 보다 넓은 정수형으로int. 이렇게 하지 않으면 컴파일러가 먼저 값을 다음으로 변환합니다.int, "승진" 규칙 때문에, 그리고 나서 목적지 유형으로.이는 거의 항상 잘못된 것이며, 오늘 처음부터 시작했다면 언어를 이런 식으로 설계하지는 못했지만 호환성을 위해 이를 고수하고 있습니다.

시스템에서 제공하는 유형은 다음과 같습니다.uint16_t,uint32_t,WORD,그리고.DWORD나나더일은수다,일수see은ete더r나,r,더,r나s )int; C++에서는 템플릿을 사용하여 알 수 있지만 C에서는 알 수 없습니다.따라서 이러한 변환과 관련된 명시적인 캐스트를 작성할 수 있습니다.

사용법 등에 따라 다릅니다.

필요한 타입을 사용할 수 있다면 그냥 타입을 사용합니다.

그렇지 않은 경우: 컴파일러는 오버플로우/언더플로우가 발생할 수 있는 데이터 유형을 암묵적으로 변환하는 경우 경고해야 합니다.그래서 저는 보통 그러한 경고를 사용하고 암묵적인 변환을 명시적인 것으로 바꿉니다.

여기에는 두 가지 접근 방식이 있습니다.

되지 않은 확신하는 하는/되지 하지/ 합니다 % 된/ 를 합니다 하는 하지 된 를 되지 .static_cast서로 을 위해.. (일반적으로 다른 API의 변환을 위해 사용됩니다.크기()가 int vs size_t)를 반환하는 것과 같습니다.

확실하지 않거나 가능할 경우 사용하는 범위를 벗어납니다.boost::numeric_cast할 때 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

예외적인 접근 방식은 손상된 데이터를 계속 사용한 후 다른 곳에서 충돌하거나 정의되지 않은 데이터로 다른 작업을 수행하는 대신 문제가 발생하면 하드/크래시/종료하는 방식을 고수합니다.

먼저 컴파일러가 캐스팅을 암시적으로 만들어 의미 있는 경고 수준에 대한 경고를 제공합니다.

수행하는 두 캐스팅은 컴파일러(또는 동료)가 자신이 맞는지 쉽게 판단할 수 없는 캐스팅이므로 명시적 캐스팅 또는 경계 테스트를 사용한 명시적 변환이 최선의 방법입니다.선택할 항목은 데이터에 대한 지식에 따라 달라집니다.가장 안전한 방법은 경계 상태를 확인하는 것입니다.가장 저렴한 방법은 간단하게 캐스트하는 것입니다(C++에서는 C 스타일 캐스트가 아닌 static_cast를 사용해주세요).

언급URL : https://stackoverflow.com/questions/39701827/c-c-best-practices-with-signed-unsigned-ints-and-function-calls

반응형