[c] POSIX 시스템에서 argc가 0이 될 수 있습니까?

기본 프로그램에 대한 표준 정의가 주어지면 :

argcPOSIX 시스템 에서 어떤 상황에서 0 이 될 수 있습니까?



답변

예, 가능합니다. 다음과 같이 프로그램을 호출하는 경우 :

또는 또는 :

그러면 “myprog”에서 argc0이됩니다.

표준 은 또한 argc호스팅 된 환경에서 프로그램 시작과 관련하여 섹션 5.1.2.2.1에 명시된대로 0 을 허용 합니다.

1 프로그램 시작시 호출되는 함수의 이름은 main. 구현은이 함수에 대한 프로토 타입을 선언하지 않습니다. 반환 유형 int과 매개 변수없이 정의되어야합니다 .

또는 두 개의 매개 변수를 사용합니다 (여기에서 argc및 로 지칭됩니다. argv이름이 선언 된 함수에 로컬이기 때문에 모든 이름을 사용할 수 있음).

또는 동등한 것; 또는 다른 구현 정의 방식으로.

2 선언 된 경우 main함수에 대한 매개 변수 는 다음 제약 조건을 따라야합니다.

  • 의 값은 argc음수가 아니어야합니다.
  • argv[argc] 널 포인터 여야합니다.

이는 argc0이면 argv[0]NULL이 보장 된다는 것을 의미 합니다. 지정자에 printf대한 인수로 사용될 때 NULL 포인터를 처리하는 방법 은 %s표준에 나와 있지 않습니다. 이 경우 많은 구현에서 “(null)”을 출력하지만 보장되지는 않습니다.


답변

다른 답변에 추가하려면 C (POSIX 여부)에는 main ()이 프로그램 내에서 함수로 호출되는 것을 방지하는 것이 없습니다.


답변

예, 0이 될 수 있습니다 argv[0] == NULL.

argv[0]프로그램의 이름 인 규칙입니다 . 당신은 할 수 있습니다 argc == 0당신과 같은 바이너리를 직접 실행하는 경우 가 execve 가족 및 인수를 포기하지 않습니다. 프로그램 이름에 가깝지 않은 문자열을 지정할 수도 있습니다. 그렇기 때문에를 사용 argv[0]하여 프로그램 이름을 얻는 것이 전적으로 신뢰할 수있는 것은 아닙니다.

일반적으로 명령 줄을 입력하는 셸은 항상 프로그램 이름을 첫 번째 인수로 추가하지만 이는 규칙입니다. 경우 argv[0]사용 == “–help”와 getopt는을 구문 분석 옵션 때문에 당신은 그것을 감지하지 않습니다 optind1로 초기화되지만 설정할 수 있습니다 optind0, 사용을 getopt표시하고 “도움말”긴 옵션을 선택합니다.

long story short : argc == 0( argv[0]그 자체로는 특별하지 않습니다) 가질 수 있습니다 . 런처가 전혀 주장하지 않을 때 발생합니다.


답변

초기 제안에서는 main ()에 전달 된 argc의 값이 “하나 이상”이어야했습니다. 이것은 ISO C 표준 초안의 동일한 요구 사항에 의해 주도되었습니다. 실제로 exec 함수의 호출자에게 인수가 제공되지 않은 경우 히스토리 구현은 0 값을 전달했습니다. 이 요구 사항은 ISO C 표준에서 제거되었으며 이후 POSIX.1-2017의이 볼륨에서도 제거되었습니다. 단어, 특히 단어의 사용은 Strictly Conforming POSIX 응용 프로그램이 exec 함수에 최소한 하나의 인수를 전달하도록 요구하므로 해당 응용 프로그램에서 호출 할 때 argc가 하나 이상임을 보장합니다. 실제로 많은 기존 응용 프로그램이 argc 값을 먼저 확인하지 않고 argv [0]을 참조하므로 이는 좋은 방법입니다.

Strictly Conforming POSIX 응용 프로그램에 대한 요구 사항은 또한 첫 번째 인수로 전달 된 값이 시작되는 프로세스와 관련된 파일 이름 문자열임을 명시합니다. 일부 기존 응용 프로그램은 일부 상황에서 파일 이름 문자열이 아닌 경로 이름을 전달하지만 argv [0]의 일반적인 사용이 진단 인쇄에 사용되기 때문에 파일 이름 문자열이 더 일반적으로 유용합니다. 어떤 경우에는 전달 된 파일 이름이 파일의 실제 파일 이름이 아닙니다. 예를 들어, 로그인 유틸리티의 많은 구현은 실제 파일 이름에 ( ‘-‘) 접두사를 붙이는 규칙을 사용합니다. 이것은 호출되는 명령 인터프리터에게 “로그인 쉘”임을 나타냅니다.

또한 test 및 [유틸리티는 모든 구현에서 결정적 동작을 갖기 위해 argv [0] 인수에 대한 특정 문자열이 필요합니다.

출처


POSIX 시스템에서 argc가 0이 될 수 있습니까?

예,하지만 POSIX를 엄격하게 준수하지는 않습니다.


답변

당신이 어떤 실행 파일을 실행할 때마다 같은 ./a.out그것은 그게 하나 개의 인수를해야합니다 program name. 그러나 Linux에서 와 argc같이 프로그램을 실행하는 것은 .zeroexecvempty argument list

예를 들어


답변

요약 : 예, argv[0]NULL이 될 수 있지만 내가 아는 좋은 / 정상적인 이유가 아닙니다. 그러나 argv[0]NULL 인지 신경 쓰지 않는 이유가 있고, 만약 그렇다면 프로세스가 충돌하도록 특별히 허용 해야하는 이유 가 있습니다.


예, argv[0]인수없이 실행 된 경우에만 POSIX 시스템에서 NULL이 될 수 있습니다.

더 흥미로운 실제 질문은 프로그램이 관심을 가져야한다는 것 입니다.

이에 대한 대답은 “아니요, 프로그램은 argv[0] NULL이 아니라고 가정 할 수 있습니다 “입니다 . 일부 시스템 유틸리티 (명령 줄 유틸리티)가 작동하지 않거나 비 결정적 방식으로 작동하기 argv[0] == NULL때문입니다. (어리 석거나 사악한 목적이 아닌) 프로세스가 왜 그렇게하는지 이유. (의 표준 사용법 getopt()도 실패 하는지 확실하지 않지만 작동 할 것으로 예상하지 않습니다.)

많은 코드와 실제로 내가 작성한 대부분의 예제 및 유틸리티는 다음과 같은 것으로 시작합니다.

이는 합리적 , 즉 실행되고있는 적어도 명령 경로를 제공하지 않고 다른 프로세스 Exec을하는 프로세스에 대한 더 좋은 이유가 없기 때문에 수용 가능한 execlp(cmd, cmd, NULL)것이 아니라이 execlp(cmd, NULL).

(그러나 파이프 또는 소켓 명령과 관련된 타이밍 경쟁 창을 악용하는 것과 같은 몇 가지 사악한 이유를 생각할 수 있습니다. 악한 프로세스는 설정된 Unix 도메인 소켓을 통해 악의적 인 요청을 보낸 다음 즉시 승인 된 희생자 명령으로 교체됩니다 (실행 최소한의 시작 시간을 보장하기 위해 인수없이) 요청을받는 서비스가 피어 자격 증명을 확인할 때 원래의 악의적 인 프로세스 대신 희생자 명령을 볼 수 있도록합니다. SIGSEGV악의적 인 프로세스에 더 큰 시간 창을 제공하는 “멋지게”동작하는 대신 강력 하고 빠르게 충돌하는 명령 ( NULL 포인터를 역 참조하여)

그 동안 즉, 가능한 프로세스가 서로하지만 원인이 인수없이 자체를 교체하는 것이 argc제로로, 그런 행동은 그렇게 할 알려진 비 사악한 이유가 없다는 엄격한 의미에서 불합리하다.

이 때문에 그리고 내가 사악하고 무관심한 프로그래머와 그들의 프로그램을 위해 삶을 힘들게 만드는 것을 좋아한다는 사실 때문에 나는 개인적으로 다음과 같은 사소한 수표를 추가하지 않을 것입니다.

특정 기존 사용 사례를 염두에두고있는 사람이 요청한 경우는 예외입니다. 그리고 나서도 조금 의심스러워서 먼저 사용 사례를 직접 확인하고 싶습니다.


답변