Submitter: Martin Sebor
Document Number: N2192
Submission Date: November 8, 2017
Subject: mtx_init behavior with an invalid mtx argument


The mtx_init(mtx_t *mtx, int type) function is described in § of C11 as follows:

-2- The mtx_init function creates a mutex object with properties indicated by type, which must have one of the six values:

-3- If the mtx_init function succeeds, it sets the mutex pointed to by mtx to a value that uniquely identifies the newly created mutex.

-4- The mtx_init function returns thrd_success on success, or thrd_error if the request could not be honored.

One of the questions raised by DR 493 is the following:

If the [mtx_init] function is required to fail when the type argument isn't valid, what is its required behavior in this case when the mtx argument is null? If the function is required to fail when the type argument isn't valid, what is its required behavior in this case when the mtx argument is null?

The committee's response is that:

6. Undefined behavior is the result of passing values other than those specified in the standard. The wording in the Standard shall change from must to shall in § p2
7. thrd_error shall be returned by mtx_init() when passed a NULL pointer.

The second part of the response (marked 7) is not supported by the standard. Since there is no mention of this "unusual" requirement in the specification of the function the blanket requirement in §7.1.4 Use of library functions applies. The blanket requirement states that:

-1- Each of the following statements applies unless explicitly stated otherwise in the detailed descriptions that follow: If an argument to a function has an invalid value (such as ... a null pointer), ...the behavior is undefined.

It is clear that the behavior of library functions is implicitly undefined when passed an invalid or null pointer unless explicitly specified oherwise. Furthermore, we do not believe the response reflects the intent of the text in § If it did, then it would require implementations to distinguish indeterminate pointers from valid ones, which has no precedent in the standard and is essentially unimplementable.

Thus, the committee's response on this point is incorrect and should be changed in DR 493.

Suggested Change

Change § p2 as indicated below:

-1- The mtx_init function initializes the creates a mutex object pointed to by mtx with properties indicated by type which must have one of the six values:

Changing the word creates to initializes in the text is in line with the coresponding text in POSIX for pthread_mutex_init and makes it clear that the object the mtx pointer need not be initialized prior to the call and thus may have an indeterminate value. (This was the subject of another question in DR 493.)

In addition, add a bullet to §J.2 Undefined behavior referencing the undefined behavior that results from invoking the mtx_init function with an invalid argument. This is necessary despite the blanket requirement in §7.1.4 because the function's behavior is also undefined when the mutex has already been initialized to a valid value by a call to mtx_init (this apsect is discussed separately in N2190), and likewise because the type argument is a valid integer that doesn't have one of the specified values.