Give me a moment to ponder the rest of it, but could you answer this
one thing to guide my future discussion points?
Initially, you were of the opinion that MILES, METERS, and int were
all distinct types, (for whatever appropriate definition of
"distinct"). I again hope we're talking at a strictly formal language
level. In that context, MILES, METERS, and int are not distinct types.
They are the same type. The size of set of types in this discussion is
1.
I again bring up 6.7.7 Type definitions / 4
typedef int MILES, KLICKSP();
[...]
The type of distance is int, [...]
So, do you agree? Or do you want to use language which says that there
are 3 distinct types, MILES, METERS, and int?
Err, that snipped quote should read:
I again bring up 6.7.7 Type definitions / 4
typedef int MILES, KLICKSP();
[...]
MILES distance;
[...]
The type of distance is int, [...]
So, I went ahead and did the rest of my reasoning. Here's what I
have:
Point 1
Let me show more conclusively that a name which refers to a type is a
different thing than the type to which it refers.
Let's look at the C standard. Again, I am referring to this
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
publicly available draft for want of the real thing, and so that
others can follow along.
"A type name is different from its type" is the simple meaning of
"6.7.7 Type definitions / 3". This is the meaning that any programmer
would take away from the English words of this section.
This is also explicitly supported by the example "6.7.7 Type
definitions / 4".
Finally, I appeal to common sense in the following way:
struct foo { int x; };
int main()
{
typedef struct foo bar;
struct foo x;
bar y;
x = y;
}
I think that all C implementations will compile this without required
diagnostic, and I hope that we can all agree that this is a well
formed, no undefined behavior program. Thus we can look at the simple
assignment rules in "6.5.16.1 Simple assignment / 1". From this, we
can conclude that the only applicable constraint is "the left operand
has a qualified or unqualified version of a structure or union type
compatible with the type of the right;". From this, we can conclude
that the "types" (quote unquote) 'struct foo' and 'bar' are
compatible. Try as I might, I can find no rules in the C standard
which says that they are compatible besides "6.2.7 Compatible type and
composite type / 1" - "Two types have compatible type if their types
are the same.". Thus we are left to conclude that 'struct foo' and
'bar' "are" the same type.
Secondly, let's take a moment and ask ourselves if this is reasonable
according to the usage of the terms in the world at large. The answer
is yes, it is. The world at large, specifically technical type theory,
generally treats two types as compatible iff they are the same type.
Obviously this is not the case for C because of separate translation
units. It's also not the case because of type qualifiers (ex: const).
It's also not the case for C because type declarations can be
"incomplete", as referenced in "6.2.7 Compatible type and composite
type / 3 and 5". However, by and large, for a single translation unit
where definitions and scope and type (for C) "make sense", it is
largely consistent.
So, a type is not the same thing as its type name, and a typedef name
does not specify a new type nor create a new type, to use the common
meaning - which is consistent with the meaning of the C standard.
Specifically, for the example
typedef MILES int;
MILES and int are both names which name the same thing. They are both
type names. They both name a type which we commonly call "int" using a
form of shorthand. In fact, this very looseness of terms is
acknowledged in "6.2.1 Scopes of identifiers / 4".
--
Point 2
Hopefully we can agree that a "type definition" is a category of
thing, where that thing "defines a type". I merely mean that the two
English formations are equivalent, and I don't mean to imply any
particular meaning to "define", "definition", "type", and so on.
--
Point 3
There is no specific passage or passages in the C standard which give
sufficient meaning to the phrase "define a type" or "type definition".
By sufficient, I mean it should be possible to look at a program and
decide if some aspect of that program does define a type, or does not
define a type, and furthermore we should be able to ascertain which
type is being defined. I find no such clear language in the C
standard. I've looked twice now.
It's hard to prove a negative -- short of proof by exhaustion. As
such, all I practically do is make this claim (again), and wait for
someone to supply chapter and verse in the standard where it does
define "type definition" or "define a type" clearly.
Yes, I do recognize that many places actively refer to such a thing.
In fact, there is even a whole section of the standard with that name,
"6.7.7 Type definitions". However, in the section "6.7.7 Type
definitions", nor anywhere else, does it give clear meaning to the
phrase "type definition" or "define a type".
Again, I have not found that clear definition of "to define a type",
but I have found clear definitions for:
* "object definitions", "function definitions", "enumeration constant
definition", "typedef name definition", from "6.7 Declarations / 5"
* "contents of a type definition", from "6.7.2.3 Tags / 1"
* and "macro definition".
Moreover, of the text which refers to type definitions (but does not
give meaning to the term "type definition"), there is great
inconsistency and there appears to be great confusion. Some places
clearly refer to a type's definitions, but then other places will
refer to that exact thing as that type's declaration. There is no
rhyme or reason which I can uncover in this. (In fact, more often than
not, such things are referred to as type declarations and not
definitions.)
Here's a somewhat comprehensive, but not complete, listing:
"5.1.2.2.2 Program execution / 1". The library clause (clause 7)
defines types.
"6.2.5 Types / 14 and 15". The implementation defines the types char,
unsigned char, and signed char.
"6.4.4.4 Character constants / 11". The header <stddef.h> defines the
integer type wchar_t.
"6.5.3.4 The sizeof operator / 4". The header <stddef.h> defines the
unsigned integer type size_t.
"6.5.6 Additive operators / 9". The header <stddef.h> defines the
signed integer type ptrdiff_t.
"6.2.5 Types / 1". Types are clearly defined in terms of values and
the types of expressions which access those values.
"6.7 Declarations / 5" clearly talks about definitions of type names,
but not types. In fact, according to this, a definition is always a
declaration, which means that a definition is something which can be
applied to an identifier, "aka a name", thus never a type. Thus, under
this definition of definition, there cannot be such a thing as a type
definition.
"6.7.2.1 Structure and union specifiers / 7" discusses when a new type
is declared, which seems to coincide with when its content is defined
(to use the term from "6.7.2.3 Tags / 1").
6.7.2.3 Tags
Constraints
1 A specific type shall have its content defined at most once.
[...]
Semantics
4 All declarations of structure, union, or enumerated types that have
the same scope and
use the same tag declare the same type. The type is incomplete111)
until the closing brace
of the list defining the content, and complete thereafter.
5 Two declarations of structure, union, or enumerated types which are
in different scopes or
use different tags declare distinct types. Each declaration of a
structure, union, or
enumerated type which does not include a tag declares a distinct type.
"6.7.7 Type definitions". Again, contrary to title, this does not
define "type definition". It does define "type name definition". It
seems non-obvious to me that a type definition is necessarily a type
name definition from the text here. In fact, this would contradict any
earlier sense of definition from "6.7 Declarations / 5" which says
that definitions only apply to names. Also, this would contradict the
meaning of "type definition" in the programming culture at large.
"6.7.7 Type definitions / 3 and 4" also clearly show that typedef does
not specify new types. First, I'd like to note that this is wrong on
some level.
typedef struct { int x; } foo;
This declaration definitely specifies a new type. However, presumably
the text of "6.7.7 Type definitions / 3" was thinking only about the
situation where there was no type content specification (to borrow the
term from "6.7.2.3 Tags / 1").
"7.1.2 Standard headers / 4". Some headers define types.
"7.6 Floating-point environment <fenv.h> / 1". This header declares
two types.
"7.8 Format conversion of integer types <inttypes.h> / 2". This header
declares some fuctions, and it declares the type imaxdiv_t, and that
type is a structure.
"7.11 Localization <locale.h> / 1 and 2". This header declares two
functions, a type, and several macros. That type is
struct lconv
"7.12 Mathematics <math.h> / 1 and 2". This header declares two
floating point types and many functions.
"7.13 Nonlocal jumps <setjmp.h> / 1". This header defines one macro,
declares one function, and declares one array type.
"7.14 Signal handling <signal.h> / 1 and 2". This header declares an
integer type, declares two functions, and defines several macros.
"7.15 Variable arguments <stdarg.h> / 1". This header declares a type
and defines four macros.
"7.17 Common definitions <stddef.h> / 1". This header defines some
integer types and defines some macros.
"7.17 Common definitions <stddef.h> / 4". The recommended practice is
that the defined types are "made" using typedef.
"7.18 Integer types <stdint.h> / 1". This header declares some integer
types.
"7.18 Integer types <stdint.h> / 4". The header shall declare the
types with typedef.
"7.19.1 Introduction / 1". The header <stdio.h> shall declare three
types, several macros, and many functions. One of the declared types
is size_t. (This is defined in the header <stddef.h> according to
other sections. Is this declaration different than those other
definitions?) One of the declared types (FILE) is an object type which
is capable of recording all the necessary state. One of the declared
types (fpos_t) is an object type and not an array type.
"7.20 General utilities <stdlib.h> / 1 and 2". This header declares 5
types, declares several functions, and defines several macros. Some of
the declared types are size_t and wchar_t (both of which are defined
in <stddef.h> according to other sections. Is this declaration
different than those other definitions?). The other three types are
structure types.
--
And hopefully you can see the pattern for the library clauses.
Specifically, for the same type, sometimes it's defined, sometimes
it's declared. Sometimes it specifically mentions that the integer
type must be "made" with typedef. Sometimes it says that the
recommended practice is that the integer type is "made" with typedef.
Sometimes it doesn't say.
Moreover, sometimes it declares macros. Sometimes it defines macros.
Unlike type definitions, there is a clear definition for "macro
definition" and there is no definition of "macro declaration", yet it
occasionally says that macros are declared, and sometimes they're
defined.
I say that you should not read into any of this at all. I claim that
when the standard talks about defining a type and declaring a type,
they're using a much more colloquial meaning of those terms. They're
generally using "definition" in the English dictionary sense to define
words and phrases (which is the exact purpose of a programming
language standard btw), though sometimes it's clear that they really
mean to say define or declare the type /name/.
Finally, I can find /clear/ language in the standard which defines
"type declarations" as opposed to type "name definitions": "6.2.7
Compatible type and composite type / 1" and "6.7.2.1 Structure and
union specifiers / 7". "6.7.2.1 Structure and union specifiers / 7" is
quite clear that certain syntax creates a new type. However, I can
still find no definition for "type definition".
What we see - arbitrary usage of declare a type and define a type - is
exactly what we would expect if the standard implicitly conflated
"names" for "the things which they name" and gave no clear meaning to
"type definition" but did give clear meaning to "type
declaration" (which is exactly what the standard does).
--
Point 4.
Having (again) concluded that the standard makes no formal definition
for "type definition", the only reasonable definition can come from
one of the standard's normative sources, or from another "reliable"
source, such as the well accepted usage in the programming community.
I do plan to get those normative sources eventually and see if they
give any better sense on type theory and type definitions. I half
expect that they would. Is there anyone offhand who has access to
those ISO docs who can review them for me?