C의 반환값 무시
최근에는 정적 코드 분석에 보풀을 사용하기 시작했습니다.제가 가끔 듣는 경고 중 하나는 이 문제에 관한 것입니다.예를 들어 다음과 같은 기능이 있다고 가정해 보겠습니다.
uint32_t foo( void );
그리고 함수의 반환값을 무시한다고 칩시다.경고를 없애기 위해 다음과 같이 쓸 수 있습니다.
(void) foo();
궁금한 것은, 이러한 코드를 「적절하게」작성하는 방법은 무엇인가, 컴파일러가 불평하지 않기 때문에, 혹은 다른 코드 유지자가 내가 반환값을 무시했다는 것을 알기 위해서, 지금까지와 같이 계속해야 하는가 하는 것입니다.
이렇게 코드를 보면(공허와 함께) 상당히 이상하게 느껴집니다.
일반적인 방법은 그냥 전화하는 것이다.foo();
에 투입하지 않고(void)
.
무시해본 적이 없는 사람printf()
첫 번째 돌을 던집니다.
저는 개인적으로 "사용하지 않은" 경고를 좋아하지만 때때로 무시해야 하는 경우가 있습니다(예:write()
사용자 또는fscanf(...,"%*s\n")
또는strtol()
이 경우 반환값은 중요하지 않으며 파일 포인터를 이동시키는 부작용만 있으면 됩니다.)
gcc 4.6에서는 상당히 까다로워지고 있습니다.
- 캐스팅 대상
(void)
더 이상 작동하지 않습니다. - 개서 기능(특히 가변)은 지루하고 서툴다.
{ssize_t ignore; ignore=write(...);}
는 다른 경고(사용되지 않음)를 표시합니다.write(...)+1
는 또 다른 경고를 발생시킵니다(syslog-value-not-used).
이것들을 억제하는 유일한 좋은 방법은 반환값을 컴파일러가 무시할 수 있는 것으로 변환하는 것입니다.
예.,(void)(write(...)+1)
.
이건 분명히 진전된 거야.+0
동작하지 않습니다(BTW).
사용하지 않는 결과를 나타내는 조금 더 "아름다운" 방법은 다음과 같습니다.
/**
* Wrapping your function call with ignore_result makes it more clear to
* readers, compilers and linters that you are, in fact, ignoring the
* function's return value on purpose.
*/
static inline void ignore_result(long long int unused_result) {
(void) unused_result;
}
...
ignore_result(foo());
와 함께C++
이것은 다음과 같이 확장될 수 있습니다.
template<typename T>
inline void ignore_result(const T & /* unused result */) {}
Clang 및 GCC 컴파일러를 사용하여 이를 수행하는 방법 중 하나는pragma
:
/* ... */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
foo(); /* this specific unused-result warning gets ignored during compilation */
#pragma GCC diagnostic pop
/* ... */
그push
-pop
콤비네이션은ignored
명령어를 사용하면 코드의 다른 곳에서 경고가 트리거될 수 있습니다.이 코드 블록이 어떤 역할을 하는지 보는 게 더 쉬울 거예요
플래그를 사용하여 코드를 컴파일하는 것을 좋아합니다.
$gcc prog1.c -o prog1.x -Wall -Wextra -ansi -pedantic-errors -g -O0 -DDEBUG=1
그리고 피하려면-Wunused-result
플래그를 하나 더 추가하는 것은 마음에 들지 않습니다.-Wno-unused-result
(해당하는 경우는, 1개의 해결책입니다).
내가 캐스팅하곤 했던 건(void)
일부 기능(비기능)의 경우printf
또는 다른 유명한 것은 컴파일러가 경고하지 않기 때문에 이상한 것만 경고합니다.)(void)
는 더 4.7.
재미있는 부목은 다음과 같이 조언합니다.
Result returned by function call is not used. If this is intended,
can cast result to (void) to eliminate message. (Use -retvalother to
inhibit warning)
하지만 이것은 더 이상 해결책이 아니다.이 문제에 대한 업데이트가 필요합니다.
이 를 아주 롭게 없애기 여기.MACRO
:
/** Turn off -Wunused-result for a specific function call */
#define igr(M) if(1==((long)M)){;}
그리고 이렇게 부르세요.
igr(PL_get_chars(t, &s, CVT_VARIABLE));
깔끔한 외관으로 컴파일러를 사용하면 코드가 삭제됩니다. 편집자의 에 표시해 주세요.vi
창, : " " " , " "igr()
;;;;;;;;;;;;;;;;;;;;;; 중창igr()
; , , , , , , , .
마찬가지로 완전히 무해한 코드이므로 C는 GCC가 허용하지 않는 것을 실행할 수 있습니다.즉, 반환 코드를 무시합니다.
★★★1==...
는 이 이 no라는 를 피하기 합니다.BOOL
GCC의 , 「GCC」라고 하는 것이 .cast
경고합니다.저는 이 테스트를 무시했습니다.double
이 매크로를 통해서도 좋았지만, 왠지 완전히 납득이 가지 않습니다.특히 함수가 포인터나 더 복잡한 것을 반환하는 경우.
이 경우 다음 사항도 필요합니다.
#define pigr(M) if(NULL==((void *)M)){;}
: ★★★★★★★★★★★★★★★★★★★★★:{;}
때문에 꼭 합니다.-Wempty-body
warning('if' 문에서는 빈 본문 주위에 괄호를 표시합니다).
그 thing이) and and and and and and and and and and and);
함수 호출은 필수는 아니지만(필수) 그 좋은 프랙티스입니다.이 보다 되어, 코드 라인의 은 「동일화」, 「동일화」로 끝납니다.;
(로 번역됩니다.)NOP
니모닉 및 최적화 후 사라짐)을 클릭합니다.
컴파일러를 실행해도 경고나 에러는 발생하지 않는다. 중splint
$ splint ./teste.c -I/usr/lib/swi-prolog/include/ -strict-lib
Splint 3.1.2 --- 20 Feb 2009
Finished checking --- no warnings
이 답변도 참조해 주세요.
다른 해결책은 실제로 값을 사용하는 것입니다., 일, 을 제거할 수 .unused variable
매크로로 경고합니다.
#define _unused(x) ((void)(x))
이 예에서는 다음과 같이 됩니다.
val = foo();
_unused(val);
반환값을 무시하는 코드를 작성하는 것은 완전히 합법적이며 경우에 따라서는 허용됩니다.아래 프로그램에서는 printf()의 반환값을 확인할 이유가 거의 없습니다.
int main(void) {
printf("Hello world\n");
return 0;
}
정적 코드 체커를 유용하게 사용하려면 무시된 반환 값도 보고해야 합니다. 이 값은 오류 추적 또는 오류 처리 누락으로 이어질 수 있습니다.
때문에 이 물건은 합니다.(void)
합니다.printf
이제 읽기 쉬운 방법으로 실행할 수 있는 몇 가지 옵션이 있습니다., 새로운 .
void printf_unchecked(const char* format, ...)
멋진 출연진이 나오는 곳이죠이 경우에는 프리프로세서 매크로를 사용하여 실행하는 것이 더 실용적일 수 있습니다.변형 변수 때문에...
gnulib에는 다음과 같은 정보가 있습니다.http://git.savannah.gnu.org/cgit/gnulib.git/tree/lib/ignore-value.h
/* Normally casting an expression to void discards its value, but GCC
versions 3.4 and newer have __attribute__ ((__warn_unused_result__))
which may cause unwanted diagnostics in that case. Use __typeof__
and __extension__ to work around the problem, if the workaround is
known to be needed. */
#if 3 < __GNUC__ + (4 <= __GNUC_MINOR__)
# define ignore_value(x) \
(__extension__ ({ __typeof__ (x) __x = (x); (void) __x; }))
#else
# define ignore_value(x) ((void) (x))
#endif
일반적으로 무시하려는 함수는 많지 않습니다.예를 들어, 부목은 특정 함수의 반환 값이 무시될 수 있음을 알려주는 특별한 주석을 추가할 수 있습니다.안타깝게도 이 경우 해당 함수와 관련된 모든 '무시 반환 값' 경고가 사실상 비활성화됩니다.
다음은 부목 청소 프로그램의 예입니다.
#include <stdio.h>
FILE /*@alt void@*/ *fopen(const char *path, const char *mode);
static int /*@alt void@*/ test(void)
{
printf( "test called\n" );
fopen( "test", "a" );
return 0;
}
int main(void)
{
test();
return 0;
}
불편한 점은 시스템 기능에 시제품을 추가해야 한다는 것입니다. 코멘트는 여기에 기재되어 있습니다.
그나저나, 기본적으로 스플린트는 수익률에 대해 불평하지 않는다.printf
libc를 사용하다단, 보다 엄격한 모드를 활성화할 수 있습니다.
린트는 비슷한 것을 사용할 수 있지만, 저는 그것을 사용해 본 적이 없습니다.다음은 설명서에 나와 있는 내용입니다.
LINT를 사용하면 C 프리프로세서의 #지시서와 유사한 명령을 사용하여 함수에 옵션 반환값을 표시할 수 있습니다.
#오토마 옵트 결과
는 옵션 결과를 반환하는 함수의 정의 바로 앞에 배치할 수 있습니다.그러면 LINT는 이 함수가 무시할 수 있는 결과를 반환함을 인식합니다. 결과를 무시해도 LINT는 오류 메시지를 표시하지 않습니다.
언급URL : https://stackoverflow.com/questions/11888594/ignoring-return-values-in-c
'source' 카테고리의 다른 글
NULL 값 및 '정의되지 않은' 값이 포함된 Prop 유형 검증을 사용하는 VueJ? (0) | 2022.08.13 |
---|---|
Vue Router에서 기본 메타 속성 설정 (0) | 2022.08.13 |
Vuex 모듈 상태가 정의되지 않음 (0) | 2022.08.13 |
Flutter.io Android 라이센스 상태 불명 (0) | 2022.08.13 |
VueJ는 div 래퍼 없이 계산된 값을 원시 HTML로 취급합니다. (0) | 2022.08.13 |