How does the word "semantic" differ from "syntactic" in C? They seem to be
contrasted.
Syntax is how the symbols are put together, according to the phrase
structure rules (or incorrectly, in violation of them).
Semantics is what they mean; their interpretation.
E.g. ``Colorless green ideas sleep furiously.'' is a syntactically valid
sentence with nonsense semantics.
These terms are so general in programming languages that the C standard has
next to zero latitude to assign these terms a different meaning.
Sometimes certain semantic feature have an obvious counterpart in the syntax,
so that a semantic distinction or invalidity can be analyzed through syntax.
For instance the semantic constraint that a declaration can specify only one
type can be expressed as a (clumsy) set of syntactic rules which generate
only valid type specifier lists. No such list contains "int char" and so
"int char" is considered syntactically invalid.
Or you can let the syntax generate any lists of type specifiers, and catch the
invalid combinations as a semantic constraint. I.e. "int char" is valid syntax,
but the meaning is recognized as nonsense.
So what makes "int char" invalid, syntax or semantics? For that we have to look
at the particulars of the language. The syntax for declarations in C clearly
over-generates (allows specifier lists that are meaningless), and the
restriction that bans "int char" is a semantic constraint rule, not expressed
in the phrase structure.
In general, anything that cannot be answered using grammar rules is an aspect
of semantics.
In C, syntax and semantics are tangled because parsing the grammar sometimes
requires semantic input, but this doesn't cause the two concepts to be mixed
up. It just means that a C program cannot be analyzed as pure syntax prior to
semantics being applied. Some semantic analysis must be applied during the
processing of the grammar rules, but that's still understood as semantic
analysis. In some constructs, a token is lexically an identifier, but the
grammar for the construct is predicated on deeper information: the phrase
structure rule requires the identifier to be semantically identified as, say,
the name of a type, and not just any kind of identifier. What the meaning of
the syntax A(B); for instance? It could be a declaration of B to be of type A,
(declarators can be parenthesized!). Or it could be a call to function A of
type B. To be able to translate the construct, the syntax has to be known, but
which syntax that is depends on looking up semantic information about A. That
being known, the parse can be completed, and later subject to more semantic
analysis.
What does the standard mean when it speaks a a "semantic type?"
I found one occurence here:
6.3.1.5 Real floating types
2 When a double is demoted to float, a long double is demoted to double or
float, or a value being represented in greater precision and range than
required by its semantic type (see 6.3.1.8) is explicitly converted
(including to its own type), if the value being converted can be
represented exactly in the new type, it is unchanged.
I don't think there is anything tricky going on here. When we look at 6.3.1.8,
it's talking about the type that ``common-real-type'' that arises from
promotions and combinations of operands in an expression.
This is probably what is understood by semantic type. I.e. it's not
syntactically apparent type; it's a type determined by semantics.
In general, type isn't syntactic. For instance if we declare ``int x;'', then
there can later be an expression ``x'' in the program. This has type int, but
that type is semantic information, not syntactic.
Some people might regard the expression 'a' as having as syntactic type,
because it's a literal constant in the syntax. I.e. that it's syntactically a
character constant, and as such could be regarded as having character type.
Regardless of that, be it right or wrong, the expression really has type int,
and this is from a semantic rule which requires expressions of type char to
undergo promotion to int. (Or, rarely, unsigned int, if an int cannot hold all
of the values of type char).