Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What are the Constraints in Standard C?

C standards talk about constraints, e. g. ISO/IEC 9899:201x defines the term

constraint
restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted

and says in chapter Conformance

If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint or runtime-constraint is violated, the behavior is undefined.

In chapter Environment, Subsection Diagnostics it is said

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined.

So, it is important to know what are the constraints in C, for example for compiler writers to judge when diagnostics are required, or for C programmers when diagnostics rather than just undefined behaviour can be expected.
Now, there are sections all over the standard document with the title Constraints, but I cannot find definitive wording as to what exactly the term constraint covers in the standard.

  • Are the constraints everything that appears in the sections titled Constraints?
  • Is every requirement that is stated outside of those sections not a constraint?
  • Is there a comprehensive description of constraint in the standard that I missed?
like image 666
Armali Avatar asked Oct 29 '15 08:10

Armali


People also ask

What are constraints in programming language?

A constraint is a relation between multiple variables which limits the values these variables can take simultaneously.

How do you define constraints in CPP?

A constraint is a requirement that types used as type arguments must satisfy. For example, a constraint might be that the type argument must implement a certain interface or inherit from a specific class. Constraints are optional; not specifying a constraint on a parameter is equivalent to using a Object constraint.


1 Answers

Are the constraints everything that appears in the sections titled Constraints?

In the sense of n1570 3.8 (a restriction imposed on programs which requires a conforming implementation to issue a compile-time diagnostic message when violated), I think yes.

Is every requirement that is stated outside of those sections not a constraint?

In the sense of 3.8, I think yes, but for a more circular reason: The standard's structure is fairly formal. Whenever applicable there seems to be an explicit Constraints section. Therefore I understand that by definition anything which is not in a Constraints section is not a constraint in the sense of 3.8.
There are a few "shall" clauses outside Constraints sections which appear completely compile-time enforceable, cf. below for a few examples. They are often in adjacent Semantics sections. I may be missing subtleties which prevent compile-time detection in the general case (so that a diagnosis cannot be made mandatory), or perhaps the standard is not completely consistent. But I would think that a compiler could simply translate a violating program, exactly because the requirements are not in a Constraints section.

Is there a comprehensive description of constraint in the standard that I missed?

I think 3.8 is all you get. I try to explore the term below and agree that the definition is unsatisfying.


I looked deeper into the standard to find that out. Here is my research.

The term constraint

Let's start with the basics. The definition of "constraint" in 3.8 which you quote is surprisingly hard to understand, at least without context ("restriction, either syntactic or semantic, by which the exposition of language elements is to be interpreted"). "Restriction" and "constraint" are synonyms, so that the rewording doesn't add much; and what is meant by "exposition of language elements"?? Exposition is a word with several meanings; let's take "writing or speech primarily intended to convey information" from Dictionary.com, and let's assume they mean the standard with that. Then it means basically that a constraint in this standard is a constraint of what is said in this standard. Wow, I wouldn't have guessed that.

Constraints as per 3.8

Pragmatically just examining the actual Constraints sections in the standard shows that they list compile time restrictions imposed on conforming programs. This makes sense because only compile-time constraints can be checked at compile time. These additional restrictions are those which cannot be expressed in the C syntax.1

Constraints outside Constraints sections

Most uses of "shall" outside of Constraints sections impose restrictions on a conforming implementation. Example: "All objects with static storage duration shall be initialized (set to their initial values) before program startup", a job of a conforming implementation.

There are a few "shall" clauses imposing restrictions on a program (not the implementation) outside of Constraints sections though. I would argue that most fall in the same category as the "runtime constraints [...] on a program when calling a library function" mentioned in 3.18. They seem to be run time constraints which are not generally detectable at compile time (so that diagnostics can not be mandatory).

Here are a few examples.

In 6.5/7 n1570 details the much-debated aliasing rules:

An object shall have its stored value accessed only by an lvalue expression that has one of the following types:

  • a type compatible with the effective type of the object
  • a qualified version of a type compatible with the effective type of the object, [...]

In 6.5.16.1, "Simple Assignment":

If the value being stored in an object is read from another object that overlaps in any way the storage of the first object, then the overlap shall be exact[..]."

Other examples concern pointer arithmetic (6.5.6/8).

Shall clauses which could be in Constraints sections

But then there are other shall clauses whose violation should be detectable at compile time; I would not have blinked if they had appeared in the respective Constraints section.

  • 6.6/6, "Cast operators in an integer constant expression shall only convert arithmetic types to integer types" (under "Semantics"); what can you detect at compile time if you cannot detect types of constants and casts?
  • 6.7/7, "If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator" (under "Semantics"). To me is seems to be a basic compiler task to detect whether a type is complete at some point in the code. But of course, I have never written a C compiler.

There are a few more examples. But as I said, I would think that an implementation is not required to diagnose violations. A violating program which manages to sneak past the compiler simply exposes undefined behavior.


1 For example, I understand that the syntax doesn't deal with types -- it only has generic "expressions". Therefore every operator has a Constraints section detailing the permissible types of its arguments. Example for shift operators: "Each of the operands shall have integer type." A program which is trying to shift the bits of a float is violating this constraint, and the implementation must issue a diagnostic.
like image 125
Peter - Reinstate Monica Avatar answered Oct 04 '22 17:10

Peter - Reinstate Monica