Question Details

No question body available.

Tags

c language-lawyer undefined-behavior c99 restrict-qualifier

Answers (2)

April 21, 2026 Score: 3 Rep: 139,442 Quality: Medium Completeness: 60%

If an implementation of strtol() were to access the string "1234" via endptr for any reason, then the restrict promise on nptr would be violated

That'a true. But an implementation doesn't need to make such an access.

Does this constitute a restrict violation according to §6.7.3.1 of C99?

No, it does not.

Specifically:

Does restrict on endptr only constrain endptr itself, or does it also constrain endptr with respect to nptr?

The former. Or, to be more exact, the restrict on endptr doesn't constrain endptr, it constrains accesses through pointers other than endptr, to the object pointed to by endptr.

However, the restrict on nptr constrains accesses to the object nptr points to, through endptr (and thus also through endptr).

If endptr and nptr point to the same memory, is that sufficient to produce undefined behaviour, even if endptr and nptr themselves are distinct?

No, that is not sufficient.

Would a hypothetical implementation of strtol() that accesses the string "1234" via endptr be considered non-conforming to the C99 standard?

Yes it would. But nobody would write such an implementation, since, again, there is no reason to access the string with *endptr.

April 21, 2026 Score: 3 Rep: 236,224 Quality: Medium Completeness: 60%

Since you have tagged this as language-lawyer, then the answer is yes (the call is “legal”) for reasons you may not have expected. However, it is also yes for the reasons you were likely concerned about.

First, as you note, the prototype of strtol is long strtol(const char restrict nptr, char restrict endptr, int base);. In this, restrict has no effect. This is because qualifiers are effectively not part of a function type. C 1999 6.7.5.3 15 states that, for purposes of compatibility between function types, “each parameter declared with qualified type is taken as having the unqualified version of its declared type.” This means that long strtol(const char restrict nptr, char restrict endptr, int base); has the same effect as long strtol(const char nptr, char endptr, int base);; the qualifiers are not part of the function type.

(The qualifiers do affect the code inside a function body, because there the qualifiers are part of the types of the parameters.)

Second, the definition of restrict imposes requirements on code that uses the identifiers (which would be code inside the implementation of the function), not on code that calls a function with qualifiers on its parameters. Therefore, the call is “legal” because it does not violate any requirements related to the qualifiers.

What you are probably wondering about is, if you call strtol as you have shown, would the code inside it satisfy the requirements on the qualifiers. From a language-lawyer perspective, we cannot know this because we cannot know what the code inside the function is. It might not even be C code, but, even if it is, there are ways to implement functions that work with overlapping memory through restricted pointers. Consider this:

void square(double  restrict result, double  restrict x)
{
    double t = x;
    t = tt;
    if (result == x)
        x = t;
    else
        result = t;
}

This code writes the result to result without violating the restrict requirements even if x and result point to the same place, because, if they do point to the same place, it uses x to access that place and does not use result.

However let’s suppose strtol was written naïvely, oblivious to the possibilities the pointers might point to overlapping memory, so that this strtol reads data through nptr (or expressions based on nptr and not endptr) and writes the end pointer through endptr (or expressions based on endptr and not nptr). Observe that all the objects in memory needed to read the string, those in the array induced by "1234", are completely separate from the str object. The formal definition of restrict in C 1999 6.7.3.1 only imposes requirements on accesses to an object X that is modified during execution of the function (in this situation). They say that if X is accessed with an lvalue based on a restricted pointer, then every access to X will be based on that pointer. For the object str pointed to by endptr, our supposition is this is true: Every access to the object str is through an lvalue based on endptr. For the objects in "1234", there is no modification to those objects, so the formal definition of restrict does not impose any requirements.

Therefore, even a naïve implementation of strtol satisfies the requirements of restrict.