C 경고 함수 호출에 sentinel이 없습니다.
이건 경고야.
Missing sentinel in function call
어떻게 제거할 수 있는지.
Linux & gcc 컴파일러를 사용하고 있습니다.
방금 같은 문제를 발견했어요.그 원인이 된 암호는...
execl("/bin/bash", "/bin/bash", fname, '\0');
하지만 그건...
execl("/bin/bash", "/bin/bash", fname, (char *)0);
첫 번째 버전의 문제는 파라미터 목록이 늘포인터로 끝나는 것입니다.그러나 '\0'은 null 포인터가 아니라 null 문자입니다.따라서 값(0)이 올바르고 유형이 잘못된 것일 뿐입니다.
(char *)0도 0이지만 늘 포인터(주소0을 가리키고 있음)인 char 포인터로 캐스트됩니다.이는 파라미터 리스트가 끝나는 곳을 시스템이 알 수 있도록 하기 위해 필요합니다.이것에 의해, 시스템은 마지막 리스트 후에 파라미터를 스캔 하지 않게 됩니다.이렇게 하면 잘못된 포인터가 수신되어 메모리를 가리킬 수 있으며, 이는 분할 장애를 일으킬 수 있습니다.
이 (char *)0은 Sentinel이라고 불리며 첫 번째 예에서 누락된 것입니다.
마지막으로 NULL은 (void *)0으로 정의되므로
execl("/bin/bash", "/bin/bash", fname, NULL);
마찬가지로 동작도 좋고, 조금 편리합니다.(@mah 덕분에)
것 .NULL
실행 시 수 가 시작되므로 할 수 null이 없으면 실행 시 어레이의 끝부분과 다음 메모리의 시작부분을 알 수 없기 때문에 메모리가 이상할 수 있습니다.
(void*)0
★★★★★★★★★★★★★★★★★」(void *)NULL
NULL
경고는 이 경고에 의해 됩니다.sentinel
지차오가 언급한 기능 속성.문서: https://gcc.gnu.org/onlinedocs/gcc-5.1.0/gcc/Function-Attributes.html#index-g_t_0040code_007bsentinel_007d-function-attribute-3226 에서 다음 내용을 확인할 수 있습니다.
이 컨텍스트에서 유효한 NULL은 모든 포인터 유형에 대해 0으로 정의됩니다.시스템에서 정수 유형을 사용하여 NULL 매크로를 정의하는 경우 명시적 캐스트를 추가해야 합니다.GCC가 stdef를 대체합니다.h는 NULL을 적절히 재정의하는 복사본입니다.
은 ANSI C의 NULL로 할 수 .0
★★★★★★★★★★★★★★★★★」(void *)0
단, 포인터만이 이 Atribute를 만족합니다.다음도 참조해 주세요.NULL, '\0'과 0의 차이점은 무엇입니까?
한편, 「 」는, 「 」, 「 」의 사이에0
정규 포인터 인수에 의해 늘 포인터에 캐스트 됩니다.제로 포인터와 제로 포인터를 vararg로 구별하는 것은 불가능하기 때문에 차이는 매우 중요합니다.참조: 포인터의 기본 인수 승격
물론 GCC는 NULL이 포인터임을 보증합니다.NULL은 GCC에 의해 제공되기 때문에stddef.h
(일부 ANSI C 헤더는 GCC에 있고 다른 헤더는 glibc에 있습니다).이것이 깨질지 어떨지는 모르겠습니다.sentinel
는 처음에 GCC 확장입니다.
하지만 난 여전히 글을 쓸 거야(void *)NULL
또는(void*)0
혹시 모르니까
또한 POSIX와man execl
sentinel 사용의 프로토타입인 execl() 함수 종료를 위해 "null pointer"가 필요합니다.
NULL
는 반드시 "null 포인터"가 아닌 "null pointer constant"이기 때문에 여기서 동작하는 것은 보증되지 않습니다.(void *)0
어디서든 잘 알려진 API로 일관성을 유지할 수 있습니다.참고 항목: (void*)0)은 늘 포인터 상수입니까?|| (int *)0은 늘 포인터입니까?
GCC 5.2.0은execl
빌트인 및 세트로서sentinel
프로그래밍 방식으로:
DEF_EXT_LIB_BUILTIN (BUILT_IN_EXECL, "execl", BT_FN_INT_CONST_STRING_CONST_STRING_VAR, ATTR_SENTINEL_NOTHROW_LIST)
glibc 2.21 버전도 있습니다.execl
Atribute가 없습니다.
NULL은 execl("/bin/bash", "ls", -l", NULL로 전달할 수 있습니다.마지막 매개 변수는 항상 0이어야 합니다.NULL 터미네이터입니다.인수 목록은 가변적이기 때문에 C에게 언제 끝날지 알려주는 방법이 있어야 합니다.
간단한 예:
#include <stdio.h>
#include <stdarg.h>
void print_strings(const char* first, ...) __attribute__((sentinel));
void print_strings(const char* first, ...)
{
va_list ap;
const char* tmp;
if (!first)
return ;
printf("%s\n", first);
va_start(ap, first);
while (1) {
tmp = va_arg(ap, const char*);
if (tmp == 0)
break;
printf("%s\n", tmp);
};
va_end(ap);
}
int main()
{
print_strings("how are you?", "i'm fine", "and you?", NULL);
return 0;
}
기본적으로 print_strings를 다음과 같이 호출하면print_strings("how are you?", "I'm fine", "and you?")
끝이 없는NULL
, GCC는 「센티넬의 누락」을 호소합니다.
sentinel 함수 속성을 함수에 추가하기 때문입니다.print_strings
변수 인수가 NULL로 끝나도록 지정하는 gcc 확장입니다. 따라서 변수 인수가 NULL로 끝나지 않으면 컴파일러가 이를 검출하여 경고를 표시할 수 있습니다.
보초병은 지키거나 보호하는 것을 의미합니다.따라서 이 컨텍스트에서는 가드 파라미터가 누락되어 있을 수 있기 때문에 에러가 발생하고 있습니다.배열 또는 사전을 사용하는 경우 오브젝트 이름 지정 후 키워드 0으로 끝나는지 확인합니다.
예:
[NSDictionary dictionaryWithObjectsAndKeys:@"UIAlertView", kSectionTitleKey,
@"Show Custom", kLabelKey,
@"AlertsViewController.m - alertOtherAction", kSourceKey];
위의 문에서는 "함수 호출에 sentinel이 없습니다"라는 오류가 발생합니다.
올바른 구문:
[NSDictionary dictionaryWithObjectsAndKeys:@"UIAlertView", kSectionTitleKey,
@"Show Custom", kLabelKey,
@"AlertsViewController.m - alertOtherAction",kSourceKey,nil];
나는 마침내 이 이상하고 짜증나는 경고를 없앨 방법을 찾았다.
적절한 포인터 타입에 영점 포인터를 던지기만 하면 됩니다.
의 경우UIAlertView
그건 이런 식이다:
UIAlertView* alert = [ [ UIAlertView alloc ] initWithTitle: @"Title" message: @"Message" delegate: nil cancelButtonTitle: @"Cancel" otherButtonTitles: @"OK", ( NSString* )nil ];
주의:( NSString* )nil
한 번 시도해보고 이것이 당신에게 적합한지 알려주세요.
Xcode에서 objective-c로 코딩하고 변수 파라미터 목록을 사용하는 메서드를 사용하는 경우 목록 끝에 0 개체를 추가해야 합니다.
예를 들어 다음과 같습니다.
NSAray * names = [NSArray arrayWithObjects: @"Name1", @"Name2"; //위의 경고가 표시됩니다.
단, NSAray *names = [NSArray 어레이 WithObjects: @"Name1", @"Name2", nil]; //정답
이게 도움이 되길 바라!
해야 한다NULL
함수의 마지막 인수입니다.
언급URL : https://stackoverflow.com/questions/2407605/c-warning-missing-sentinel-in-function-call
'programing' 카테고리의 다른 글
SLF4J: "org.slf4j.impl" 클래스를 로드하지 못했습니다.Static Logger Binder" (0) | 2022.07.11 |
---|---|
jQuery 약속을 반환하는 Vuex 작업이 작동하지 않습니다. .fail은 함수가 아닙니다. (0) | 2022.07.11 |
리덕스 셀렉터와 같은 Vuex 셀렉터 (0) | 2022.07.11 |
"Vue 유형에 속성이 없습니다" 오류 해결 (0) | 2022.07.11 |
자바 룩앤필(L&F) (0) | 2022.07.11 |