The system function in C++

Looking at the function description system And I noticed two strange places:

If command is not a null pointer, the value returned depends on the system and library implementations, but it is generally expected to be the status code returned by the called command, if supported.

What is meant by "generally expected"? In what cases can it turn out that the returned value is not a return code? And what is it then is?

If command is not a null pointer, it causes undefined behavior.

But that's what the function is for, to execute commands that are obviously not null. What kind of undefined behavior and under what conditions are we talking about?

PS: In another source, the return value is not associated with the executed command at all (unless it is null) - it simply says "Implementation-defined value". And no mention of UB.

Author: Mikhailo, 2019-01-11

2 answers

If you look in the draft of the C++ standard (N4791), you can find only a couple of scant mentions of the function system.

  1. In section 16.2.2, describing the header file <cstdlib>. And it just presents its signature:

    int system(const char* string);
    
  2. In section 16.12 Other runtime support:

    Headers <csetjmp> (nonlocal jumps), <csignal> (signal handling), <cstdarg> (variable arguments), and <cstdlib> (runtime environment getenv, system), provide further compatibility with C code.

Actually, from point 2. it becomes clear that it is necessary to look for the description already in the sishny standard. Well, there (C11) we see the following (7.22.4.8):

Description

If string is a null pointer, the system function determines whether the host environment has a command processor. If string is not a null pointer, the system function passes the string pointed to by string to that command processor to be executed in a manner which the implementation shall document; this might then cause the program calling system to behave in a non-conforming manner or to terminate.

Returns

If the argument is a null pointer, the system function returns nonzero only if a command processor is available. If the argument is not a null pointer, and the system function does return, it returns an implementation-defined value.

You can see that there is no mention of UB here, but there is a requirement for the implementation to provide appropriate documentation on how the command processor called via system should work and whether it exists at all. And there is a phrase very similar in possible outcome to UB:

... to behave in a non-conforming manner or to terminate.

My translation:

... behave inappropriately or terminate.

But due to the fact that this is all left to the implementation-this is not UB from the point of view of the language standard.

So in case of difficulties with interpretation, you should still refer to the standard (at least a draft), and not rely on descriptions from other sites. For the sake of interest, I looked at the web archive version of the page cplusplus.com from November 2012 and there about UB too there's nothing. I fully assume that in the current version of the page, they just decided to decipher the phrase I mentioned in such a simple way. For example, the situation with system(nullptr) is portable, and everything else is not and wait for trouble.

As for "generally expected" , it seems to have already been answered, the point is not to shift the behavior of the system where the compiled code will be executed to the language standard, so a certain best-known case is proposed. And what will some people write there? other implementations, and what this code should mean in them , is a matter for the implementations themselves, not for the C language.

 4
Author: αλεχολυτ, 2019-01-13 18:31:18
  1. In general, the language does not require the runtime to have such a thing as a "command return code"at all. Maybe no "return code" is supported at all in the runtime's command processor, or the approach used to return the completion status is not naturally compatible with the int type. Therefore, the language specification cannot/does not want to impose such a requirement.

    P.S. The specification of this behavior is similar in its general nature, for example, specifications for conversions between pointer and integer types. It is clear to everyone that in general is expected to simply convert the address value. But the language specification does not specify the details of the internal representation of pointers and does not want to impose this behavior.

  2. Where did the mention of "undefined behavior" come from-we need to understand. I don't see such a direct statement in the language standard. Although there is a certain logic in it: the execution of the command the command processor can lead to any results, and the description of the behavior of such commands is beyond the scope of implementation-defined.

 5
Author: AnT, 2020-06-12 12:52:24