If you could change the C or C++ or Java syntax, what would you like different?

F

Felix Palmen

* Seebs said:

Depends on what picture we're talking about here. I never said it would
be /wrong/ to know what's going on under the hood. It certainly won't
hurt. But this started out with the claim that typedef was a misnomer
and I say it clearly isn't, because the appropriate abstraction level is
that of the programmer's intent.
I am not aware of anything prohibiting an implementation from having,
e.g., a size_t which does not correspond to ANY type you can declare by
ANY other means. At which point, it's only an alias for __internal_uint48_t
or whatever... and it's functionally completely distinct.

It would probably break some code ... or, to be more precise: expose
some broken code.

Regards,
Felix
 
J

Joshua Maurice

Depends on what picture we're talking about here. I never said it would
be /wrong/ to know what's going on under the hood. It certainly won't
hurt. But this started out with the claim that typedef was a misnomer
and I say it clearly isn't, because the appropriate abstraction level is
that of the programmer's intent.

No. One cannot use this line of thinking. The appropriate "abstraction
level", or what I call "the appropriate definition of terms" is not
programmer intent. It's what the language standard says. The
programmer may well want to define a new type, and perhaps that's why
the thing is currently called "typedef", but that does not mean it
defines types. Insisting that it does leaves us at a conundrum, two
different sets of vocabulary which are inconsistent. I suggest that we
drop the informal "programmer's intent" in favor of the much more
formalized and widely known and accepted standard of the C language
standard.

In other words, please stop attempting to redefine terms because it
suites your purposes. "Defining a (new) type" already has a very well
defined and understood definition.

Furthermore, it's not only not "wrong" to know what's going on "under
the hood", but it's required. This is not some little arcane magic
that's invisible to the programmer. It is a visible aspect of the type
system and the programming language. Ideally, everyone would know
everything about their programming language, but that's not possible.
However, that is a goal we should all strive for. You need to
understand why
#include <stddef.h>
int main()
{
size_t * x;
unsigned int * y = x;
}
will compile on some systems and not others. The answer is because
size_t may very well be a typedef for "unsigned int", and it might
not. We all rely on the type system to catch simple programming errors
of incompatible types. The enforced type system is a very good tool
that helps productivity. You need to understand it in order to gain
the maximum productivity benefit.
 
F

Felix Palmen

* Joshua Maurice said:
No. One cannot use this line of thinking. The appropriate "abstraction
level", or what I call "the appropriate definition of terms" is not
programmer intent. It's what the language standard says.

You're way off the point.
In other words, please stop attempting to redefine terms because it

I don't. The term is defined somehow and named somehow and I didn't
change any of that. So, please stop posting nonsense.
 
J

Joshua Maurice

You're way off the point.


I don't. The term is defined somehow and named somehow and I didn't
change any of that. So, please stop posting nonsense.

"define a type" means "define a new type", where "new" means "distinct
from all other defined types - distinct in the sense distinct to the
type system and type checker. Typedef does not do that. It does not
matter what is the "programmer's intent", which you said in the now-
snipped quote. That is where you are wrong. The programmer's intent is
entirely irrelevant to the discussion of what it means to define a
type, and whether typedef defines types.
 
F

Felix Palmen

* Joshua Maurice said:
"define a type" means "define a new type", where "new" means "distinct
from all other defined types - distinct in the sense distinct to the
type system and type checker. Typedef does not do that. It does not
matter what is the "programmer's intent", which you said in the now-
snipped quote. That is where you are wrong. The programmer's intent is
entirely irrelevant to the discussion of what it means to define a
type, and whether typedef defines types.

You STILL completely miss the point. What it "means to define a type" is
irrelevant. Especially under the narrow and very specific nomenclature
of the C language standard. As long as you don't even remotely
understand my argument supporting the name "typedef", it's completely
pointless to repeat yourself over and over again. Therefore, last f'up
from me to one of your postings, at least in this thread.
 
J

Joshua Maurice

You STILL completely miss the point. What it "means to define a type" is
irrelevant. Especially under the narrow and very specific nomenclature
of the C language standard. As long as you don't even remotely
understand my argument supporting the name "typedef", it's completely
pointless to repeat yourself over and over again. Therefore, last f'up
from me to one of your postings, at least in this thread.

Could you please be more clear in the future? I don't know what you
mean by "last f'up from me". Are you admitting that you were wrong in
content? Or are you simply stating that it was a mistake to reply to
me?

So, my point is simple. There is already a nomenclature that defines
terms, such as "define a type", "typedef", "define type names" (which
should really read: "declare type names" to be more internally
consistent, but oh well), and so on. I posit that we should stick to
one nomenclature at a time, and that we should not introduce another
nomenclature with the same names in the same context because that
would cause undue confusion.

Specifically, in a previous post, you said:
But this started out with the claim that typedef was a misnomer
and I say it clearly isn't, because the appropriate abstraction level is
that of the programmer's intent.

Your argument is that typedef is not a misnomer because it's sensible
and consistent with programmer's intent. Implicit in this argument is
the argument that programmer's intent is a proper basis for the
definition of terms. I reject that standard of definitions in this
context for the aforementioned reasons. We should use the C language
standard's definition of terms when discussing something defined in
the C language standard.
 
S

Seebs

"define a type" means "define a new type", where "new" means "distinct
from all other defined types - distinct in the sense distinct to the
type system and type checker.

What causes you to believe that this is what "define a type" means, or what
"new" means?

This clearly contradicts multiple examples of how the C standard uses
the term. Maybe it's what you think they should have meant, but it's quite
simply not what the standard actually says.

-s
 
K

Keith Thompson

Keith Thompson said:
Agreed.

But if you don't care that they're aliases for *something*, then your
missing part of the picture.

s/your/you're/

(Of course I noticed the error just *after* I sent the article.)
 
K

Keith Thompson

Seebs said:

Yes, I think so. You understand what typedef does. Would you be better
off, or even as well off, if you didn't?
Under what circumstances will I benefit from knowing that two types which
are logically distinct are actually physically the same? What will I do
with that information?

Understand error messages, or their absence, for starters.
And understand something about the language you're using, which is
a good thing in itself.
True. I think that's why I like "define" -- definitions are not usually
expected to create new words.

Or new types.
 
S

Seebs

Yes, I think so. You understand what typedef does. Would you be better
off, or even as well off, if you didn't?

Oh, I think it's useful to know what it does. I was asking specifically,
though, about "which types are really distinct and which are distinct
only on a higher level of abstraction".

I'm not at all sure that knowing which types are which is useful to me.
Knowing that the categories exist, and may produce surprising results,
is pretty useful. I don't know that I've ever had occasion to need
to know which specific types are in them, though.
Understand error messages, or their absence, for starters.
And understand something about the language you're using, which is
a good thing in itself.

Hmm. I suppose as a debugging tool it's useful -- I'd put it in the
same bin as knowing the calling conventions of a given ABI. Useful,
but only when something's already gone wrong.
Or new types.

Hmm. Yeah. C's got a weird thing going, as does a fair bit of mathematics,
in that "define" is often very close to "create".

I think what we've got here is two competing models of the C type system,
both of which, so far as I can tell, are quite consistently able to
correctly predict outcomes, both of which match at least the semantics
of the standard, and so on.

So far as I can tell, your model and mine produce absolutely equivalent
results. We're definitely looking at the same rug, we've just pushed
the little lump in it into different places. I handle the quirks of
C's type system by observing that, quite often, two types are actually
indistinguishable to the compiler, but it's still useful to think of
them as logically distinct. You handle it by saying a single type can
have multiple names. So far as I can tell, neither of these produces
bad code in any case.

-s
 
J

Joshua Maurice

What causes you to believe that this is what "define a type" means, or what
"new" means?

This clearly contradicts multiple examples of how the C standard uses
the term. Maybe it's what you think they should have meant, but it's quite
simply not what the standard actually says.

Ok. Pedantic mode.

Claim 1- I claim that the C standard never defines "to define a
type".

Claim 2- I further claim that the only sensible meaning of the phrase
"to define a type" is to introduce or create a new, previously un-
created type, which is distinct from all other types with regards to
the type system.

----

First claim, that the C standard never defines "to define a type".

I'm referencing ISO/IEC 9899:TC3. A copy can be found at the link:
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

The term "definition" has a particular meaning in C. All C-definitions
are C-declarations. C-declarations declare C-identifiers. A C-
definition is a property or quality of a C-declaration and of the
associated C-identifier. (See 6.2.1 Scope of Identifiers / 1, 6.2.1
Scope of Identifiers / 4, 6.7 Declarations / 5.)

In particular, a typedef name is declared and defined by a "typedef
statement". (See 6.2.1 Scope of Identifiers / 4, 6.7 Declarations / 5,
6.7.7 Type definitions / 3.)

A typedef name is distinct from the thing to which it refers. (See
6.2.1 Scope of Identifiers / 6.) The standard adopts a loose use of
terminology and uses the name as equivalent to the named thing, but it
says that sometimes the difference is important and it will be
explicitly called out.

The C language standard does not define or use the term "define a
type" explicitly. Instead uses the term "type specifier". (See: 6.2.1
Scope of Identifiers / 4, 6.2.7 Compatible type and composite type /
1.)

One aside:
struct { int x; };
is illegal C code AFAIK. One might say that it defines a type if it
were legal, but there's a strict requirement in the C standard that
all definitions are declarations, and no identifier is declared, so it
is illegal. Of fun note is that we can "fix it" by various means:

Declare and define a variable.
struct { int x; } y;

Declare and define a struct tag.
struct foo { int x; };

Declare and define a typedef name.
typedef struct { int x; } foo;

Note that each of the above is a declaration and a definition
according to the rules of the C standard. Note specifically that we
can "fix" the code "struct { int x; };" by declaring /an object/ or by
declaring /an identifier related to types/ - a struct tag or a typedef
name. Please see that this means that the C standard never talks about
defining types, merely defining type names. There is no well defined
thing called a "type definition" in the C standard, despite the
section in the C standard with that name.

----

Second claim, that the only sensible meaning of the phrase "to define
a type" is to introduce or create a new, previously un-created type,
which is distinct from all other types with regards to the type
system.

Let me work through these questions, and hopefully we can come to some
understanding.

At the very least, types can be "compatible" and they can be not
"compatible", aka "distinct". The words "distinct" and "compatible"
when applied to types refers to how it interacts in the type system. I
think that wiki phrases it quite well:

http://en.wikipedia.org/wiki/Type_system
In computer science, a type system may be defined as "a tractable syntactic framework for classifying phrases according to the kinds of values they compute".[1] A type system associates types with each computed value. By examining the flow of these values, a type system attempts to prove that no type errors can occur. The type system in question determines what constitutes a type error, but a type system generally seeks to guarantee that operations expecting a certain kind of value are not used with values for which that operation makes no sense.

In a type system, there are things called "type errors" when one tries
to do an operation on "values" which "makes no sense". In the C word,
simple assignment is such an operation. For the simple assignment "a =
b;", this will produce a type error when the types of the "values" are
such that the simple assignment "makes no sense". C formalizes this to
mean that the types must be "compatible" or that there exists a (type)
conversion of the right hand side to a type which is "compatible" with
the left hand side.

So, there are types which are "compatible" and there are types which
are "not compatible". One can use the compiler to check by seeing if
we can get "type errors".

Moreover, "compatible" is a binary relation on the set of types.
Obviously it must be an equivalence relation.

I suspect for most programming languages, this "compatible"
equivalence relation is a trivial reflexive relation - a relation
where two elements are "compatible" iff they are the same element. At
the very least, it is a trivial reflexive relation in C. "Two types
have compatible type if their types are the same" (6.2.7 Compatible
type and composite type).

So, two types are compatible
iff they're the same type
iff the type checker of the type system says that they're compatible.

The final question is simple. Can you "define" a specific type more
than once in a specific translation unit? Not the type name aka
identifier, but the actual type.

I see these as the available options:

Option 1- typedef defines a new type.

This is patently false. Let's consider:
struct foo { int x; };
typedef struct foo bar;
int main()
{
struct foo * x;
bar * y = x;
}

We can look over the implicit conversion rules and the constraints in
the C standard, and we can conclude that the type of " * x" and " * y
" must be "compatible" (technical term in the C standard) for this to
compile. (See: ISO/IEC 9899:TC3 - 6.5.16.1 Simple assignment / 6.) We
can then conclude that the types are the same type from the previous
discussion. Thus typedef does not define new types.

Finally, also from the C standard. "A typedef declaration does not
introduce a new type, only a synonym for the type so specified." -
"ISO/IEC 9899:TC3 - Type definitions / 3". A typedef does not
introduce a type. It introduces a synonym for a type. Under any sane
definition of "define a type", typedef does not.

Option 2- typedef defines a type, but that type is already defined.
typedef defines the type /again/. One might say it "redefines" it.

This very much goes against the meaning of the word "define" and
"definition".

An English word in a dictionary can have more than one meaning.
Commonly it is said that the word has more than one definition.
However, this is in a different sense that "defining a type". The
entry in the dictionary itself can be thought of as a singular
definition, made at one instant, inseparatable. It merely has several
meanings based on context, usage, and even then perhaps is ambiguous.
The key is that even English words in a dictionary are only "defined
once". You won't see an entry for a word, then on the next page see
another entry for the same word. In that sense, "definition" is a
singular event. In this sense, the word is defined, and another entry
wouldn't be "define the word again" - it would "redefine" the word.

Also, words can have different definitions based on context. "Metal"
in astrophysics refers to all elements besides Hydrogen and Helium,
but "metal" in chemistry refers only to the transition metals in the
"middle" of the periodic table. In our case, we're restricting our
context to the C programming language, or maybe all programming
languages. As such, we don't have this crossover of terms from
different domains.

I claim that a programming language is similar to the English
dictionary with regards to our problem. A declaration of a program
unambiguously gives meaning to the identifier for its scope. There is
no way to redefine the meaning an identifier in its scope. It's
meaning is set on first use. This is very much like the English
dictionary; each entry as a singular event gives meaning to the word
being defined. To say "define a type which already exists" simply goes
against how the words are commonly used in programming circles.

Any sensible way you look at it, in the programming world you never
define something which has already been defined. As an example, C++
calls this the One Definition Rule - each thing must have at most one
definition (per translation unit), and C++ very clearly spells out the
typedef is not a definition of a type.

In fact, the definition of "definition" in the C standard carries the
same connotation of "singular". (See ISO/IEC 9899:TC3 - 6.7
Declarations / 5.) Each definition of a particular object, function,
enumeration constant, and typedef name, can only happen once (per
translation unit). There is no defining the same thing multiple times.
It would be nonsensical to say you can define a specific type more
than once (in a single translation unit).

Finally, also from the C standard. "A typedef declaration does not
introduce a new type, only a synonym for the type so specified." -
"ISO/IEC 9899:TC3 - Type definitions / 3". A typedef does not
introduce a type. It introduces a synonym for a type. Under any sane
definition of "define a type", typedef does not.

That leaves us with:

Option 3- typedef does not define types.

----

To sum this all up, I have yet to see any contradictory usage of the
terms from reliable text, such as a programming language definition, a
paper written by a programming language expert, etc. Also, I have
found evidence from other programming language communities which
agrees with me (C++ standard). Finally, I have shown that this is the
only sensible definition of "to define a type" which is consistent
with the C standard.
 
J

Joshua Maurice

So far as I can tell, your model and mine produce absolutely equivalent
results.  We're definitely looking at the same rug, we've just pushed
the little lump in it into different places.  I handle the quirks of
C's type system by observing that, quite often, two types are actually
indistinguishable to the compiler, but it's still useful to think of
them as logically distinct.  You handle it by saying a single type can
have multiple names.  So far as I can tell, neither of these produces
bad code in any case.

I don't understand your model then, or you are mistaken. Please
explain to me the following things in the nomenclature of your model
to help me understand your model.

/*all C code*/

int main()
{
struct foo { int x; };
struct bar { int x; };
struct foo * x;
struct bar * y = x; /*compiler error*/
}
Why does the above program have a compiler error?

int main()
{
struct foo { int x; };
typedef struct foo bar;
struct foo * x;
bar * y = x;
}
Why is the assignment / initialization of "y = x" well formed?

#include <stddef.h>
int main()
{
size_t * x;
unsigned int * y = x; /*possible compiler error*/
}
Why does this compile on some systems, and not on others?
 
S

Seebs

I don't understand your model then, or you are mistaken. Please
explain to me the following things in the nomenclature of your model
to help me understand your model.
/*all C code*/

int main()
{
struct foo { int x; };
struct bar { int x; };
struct foo * x;
struct bar * y = x; /*compiler error*/
}
Why does the above program have a compiler error?

Because struct foo and struct bar are distinct types, which the compiler
is able to tell apart.
int main()
{
struct foo { int x; };
typedef struct foo bar;
struct foo * x;
bar * y = x;
}
Why is the assignment / initialization of "y = x" well formed?

Because 'bar' and 'struct foo *' are interchangeable, so the compiler
can't tell them apart.
#include <stddef.h>
int main()
{
size_t * x;
unsigned int * y = x; /*possible compiler error*/
}
Why does this compile on some systems, and not on others?

Because, while size_t and unsigned int are logically distinct types,
on some systems the compiler can't tell them apart.

-s
 
A

Alan Curry

Intention is irrelevant. You may intend for them to be two different
things, and they are two different things in your model, but they may
not be two different types in the C programming language. Types in the
C programming language are defined with regards to the type checker.

Intention is important, even when the tools used don't enforce or
understand it. Source code is used to communicate ideas to other
programmers, not just to the computer.
 
S

Seebs

Claim 1- I claim that the C standard never defines "to define a
type".

Defines it in those exact words, no. Describes "type definitions",
gives a meaning for "defining" a type name, and refers repeatedly
to types as being "defined", yes.
Claim 2- I further claim that the only sensible meaning of the phrase
"to define a type" is to introduce or create a new, previously un-
created type, which is distinct from all other types with regards to
the type system.

This is a pretty interesting claim. How does it mesh with your understanding
of the phrase "to define a word"? How about "to define an inline function"?
A typedef name is distinct from the thing to which it refers. (See
6.2.1 Scope of Identifiers / 6.) The standard adopts a loose use of
terminology and uses the name as equivalent to the named thing, but it
says that sometimes the difference is important and it will be
explicitly called out.
Yes.

The C language standard does not define or use the term "define a
type" explicitly. Instead uses the term "type specifier". (See: 6.2.1
Scope of Identifiers / 4, 6.2.7 Compatible type and composite type /
1.)

7.17 Common definitions <stddef.h>

The following types and macros are defined in the standard
header <stddef.h>.

The *types* are *defined*.
Note that each of the above is a declaration and a definition
according to the rules of the C standard. Note specifically that we
can "fix" the code "struct { int x; };" by declaring /an object/ or by
declaring /an identifier related to types/ - a struct tag or a typedef
name. Please see that this means that the C standard never talks about
defining types, merely defining type names. There is no well defined
thing called a "type definition" in the C standard, despite the
section in the C standard with that name.

If there were, there would be a crucial distinction to be drawn between
"defining a type" and "defining a type name". But there isn't. So there
isn't. What's left is to observe the consistent usage of phrases
such as "types ... are defined" to refer to the definition of type-names.
Moreover, "compatible" is a binary relation on the set of types.
Obviously it must be an equivalence relation.

Given:
extern signed long sl;
extern signed short ss;
and assuming that both objects hold values which are not trap
representations, consider:
ss = sl; /* may be undefined behavior */
sl = ss; /* is not undefined behavior */
Option 1- typedef defines a new type.
This is patently false.

No, it isn't.
Let's consider:
struct foo { int x; };
typedef struct foo bar;
int main()
{
struct foo * x;
bar * y = x;
}
We can look over the implicit conversion rules and the constraints in
the C standard, and we can conclude that the type of " * x" and " * y
" must be "compatible" (technical term in the C standard) for this to
compile. (See: ISO/IEC 9899:TC3 - 6.5.16.1 Simple assignment / 6.)
Agreed.

We can then conclude that the types are the same type from the previous
discussion. Thus typedef does not define new types.

I am not convinced that we can draw this conclusion. We certainly know
they're compatible. We know that types which are the same type are
compatible. However, this does not mean that there is no other way that
two types could be compatible.
Finally, also from the C standard. "A typedef declaration does not
introduce a new type, only a synonym for the type so specified." -
"ISO/IEC 9899:TC3 - Type definitions / 3". A typedef does not
introduce a type. It introduces a synonym for a type. Under any sane
definition of "define a type", typedef does not.

I don't think so, simply because the common English meaning of the word
"define" is unambiguously "sane". To give a definition of; not to create.
An English word in a dictionary can have more than one meaning.
Commonly it is said that the word has more than one definition.
However, this is in a different sense that "defining a type".

It's not different from the sense in which I would usually talk about
defining a type.
The key is that even English words in a dictionary are only "defined
once". You won't see an entry for a word, then on the next page see
another entry for the same word.

Well, you will sometimes. Or perhaps it's two words which happen to be
written the same. :p
In that sense, "definition" is a
singular event. In this sense, the word is defined, and another entry
wouldn't be "define the word again" - it would "redefine" the word.

But something else could define a different word to be the same thing.

colour, n.: Alternative spelling of color.

Behold! It is a definition. It does not create a word. It does not
"redefine" another word. And yet, it defines one word to be the same
as another.
Any sensible way you look at it, in the programming world you never
define something which has already been defined.

But you can certainly define something to be the same as something else!
To sum this all up, I have yet to see any contradictory usage of the
terms from reliable text, such as a programming language definition, a
paper written by a programming language expert, etc.

I suppose people who were involved with writing the standard are not
technically "experts", true.

But I've given many examples of contradictory usage in the standard itself.
In particular, the standard seems quite clear and consistent in treating
"typedef name" and "type" as essentially interchangeable while discussing
the behavior of the standard headers. Types and macros are defined
in <stddef.h>. We are told that <stdint.h> "declares sets of integer types",
and then we see "... <stdint.h> shall declare that typedef name and
define the associated macros." In 7.18.1.1, we see:
The typedef name intN_t ...
[...]
These types are optional.

In 7.18.1.2, after introducing "the typedef name int_leastN_t", the standard
goes on to say "The following types are required:", and lists typedef names.

In short, the standard is quite consistent about not being consistent in
this; the terms are repeatedly treated as functionally interchangeable.
Also, I have
found evidence from other programming language communities which
agrees with me (C++ standard).

This is completely irrelevant; the C++ standard and the C standard disagree
on a great deal of terminology.
Finally, I have shown that this is the
only sensible definition of "to define a type" which is consistent
with the C standard.

Only you haven't. You've repeatedly asserted it, but you have yet to
demonstrate that the alternative model I use is incorrect or contradicts
the standard any worse than yours does. (Both contradict at least some
of the text, since the text itself is pretty much agnostic on the issue.)

If we start with the clear language in the standard governing "defining
typedef names" (which is clearly and unambiguously correct), and combine it
with the general disregard for any hypothesized distinction between typedef
names and types, we find that it is perfectly reasonable to refer
to typedef as "defining types", because the language spec does not
consistently distinguish between typedef names and types.

So far as I can tell, the standard has two modes of discussion of this. One
is the sense in which a distinction is being drawn between creating a new
type and merely creating a synonym for it, and in this context, we find
that typedef is merely defining "typedef names". The other is the sense
in which we are not talking about the underlying mechanics, but the effect
on a program, and the way a programmer interacts with type names; in this
sense, we find that "defines an identifier to be a typedef name" and "defines
a type" are functionally interchangeable.

In short, if you just want to write code, you can refer to typedef as
defining types, and nothing will go wrong. If you want to write a compiler,
there will be an afternoon or so during which you need to distinguish between
"new types" and "new typedef names", after which it stops mattering again.

Now, it's entirely possible that you know a great deal more about the standard
than the people who wrote it, and that we were all fools to refer to headers
as defining types, but it seems more reasonable to me to just assume that we
used that wording because it was clear, unambiguous, and communicated
correctly what it needed to communicate.

-s
 
S

Seebs

Intention is important, even when the tools used don't enforce or
understand it. Source code is used to communicate ideas to other
programmers, not just to the computer.

Yeah. This is why I avoid trying to find out whether, say, uid_t and
int are the same type -- there's no way I could use that information
to improve a program.

-s
 
J

Joshua Maurice

Because struct foo and struct bar are distinct types, which the compiler
is able to tell apart.

K. Good good. Distinct types.
Because 'bar' and 'struct foo *' are interchangeable, so the compiler
can't tell them apart.

C language standard draft,
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
6.2.7 Compatible type and composite type / 1
Two types have compatible type if their types are the same. [...]

So, the types referred to by the type names "struct foo" and "bar" are
the same type.

Thus, your choices appear to be:

1- "typedef struct foo bar;" does not define types.
2- "typedef struct foo bar;" defines a type which is already defined.
3- "define a new type" is uselessly vague w.r.t. C and should be
avoided.

1 is my position.

2 is unappealing because it contradicts the intuitive notion that
definitions happen only once, because it contradicts the "spirit" of
the C standard which requires that definitions only happen once (per
translation unit), because it contradicts other language standards and
usages such as the C++ ODR rule et. al., and because most other
competent programmers think it's 2.

3 is unappealing because it takes a commonly used phrase and says it's
meaningless.

However, I do want to stress that any answer but 1 is an individual's
lone attempt to fiat the definitions to something other than what is
commonly understood.
Because, while size_t and unsigned int are logically distinct types,
on some systems the compiler can't tell them apart.

First, let me introduce you to:

C language standard draft,
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
7.17 Common definitions said:
Recommended practice
4. The types used for size_t and ptrdiff_t should not have an integer conversion rank greater than that of signed long int unless the implementation supports objects large enough to make this necessary.

So, it's recommending the practice that size_t is defined as a
typedef, presumably of one of the "basic" integer types.

Thus, in short, your answer is bullshit.

For one, your answer lacks predictive and explanative power. I am
unable to determine when "x = y" is valid code, nor why it might be or
might not be. Your answer is "can't figure it out / whatever the
compiler feels like".

However, it's mostly bullshit because you just chose to ignore large
swathes of the C standard and type theory at large. C is a strongly
typed, statically typed programming language. (Well, for some
definition of "strongly".) The C standard requires that a conforming
compiler issue a diagnostic when certain constraints are violated. The
above example is a constraint violation on some systems and not on
others /precisely because size_t is a different type on some systems
and is the same type on others/.

Your answer that "size_t is special with regards to the type system"
is specious. The C standard when describing the type system
constraints makes no such allowance. "unsigned int" and "size_t" are
either the same type and the assignment is valid, or they're different
types, the program is ill-formed, and a diagnostic will be issued.
There is no other option. (However, if size_t were void, then the
above would work because of the void* implicit conversion rules, but I
ignored that case because it's otherwise required that size_t is an
integer type.)

size_t may be a distinct type from all other "basic" integer types (as
far as I can tell), and it may be a typedef of a "basic" integer type
(which is the recommended practice). Also, the answer can change from
implementation to implementation. If it compiles, then they're the
same type on that implementation. If it doesn't compile, then they're
not the same type on that implementation. End of story.
 
J

Joshua Maurice

Intention is important, even when the tools used don't enforce or
understand it. Source code is used to communicate ideas to other
programmers, not just to the computer.

"Intention of a single programmer" is not a valid standard of
definition of terms of a language standard. The language standard,
experts, and the community at large is a valid standard of definition
of terms of a language standard.

Put another way: Intention is important to understanding code. I don't
dispute that. However, some lone dude's intention when using the
standard is irrelevant when discussing technical definitions of a
technical standard.
 
S

Seebs

C language standard draft,
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
6.2.7 Compatible type and composite type / 1
Two types have compatible type if their types are the same. [...]
So, the types referred to by the type names "struct foo" and "bar" are
the same type.

Not necessarily! There are multiple rules for when types are "compatible".

The relation we have here is that if two types are the same, they are
necessarily compatible. That does not imply that if two types are
compatible, they are necessarily the same! There are other ways two
types can be compatible, as you'd know if you finished reading the
paragraph.

The reason for all that fancy language about two types having the
same definition is there because each translation unit has its own
local "types" -- so if you're linking two things that both use "struct
foo", they have different types which are compatible.
First, let me introduce you to:

As previously noted, I'm one of the people who WROTE this specification. I
am basically familiar with it. :)
So, it's recommending the practice that size_t is defined as a
typedef, presumably of one of the "basic" integer types.
Yes.

Thus, in short, your answer is bullshit.
No.

For one, your answer lacks predictive and explanative power. I am
unable to determine when "x = y" is valid code, nor why it might be or
might not be. Your answer is "can't figure it out / whatever the
compiler feels like".

This is totally untrue. It's easy to find out -- however, in the case
where we have a "foo" and a "bar", my answer is "you shouldn't care,
because it is logically wrong to treat them as compatible even if they
are".
Your answer that "size_t is special with regards to the type system"
is specious.
Huh?

The C standard when describing the type system
constraints makes no such allowance. "unsigned int" and "size_t" are
either the same type and the assignment is valid, or they're different
types, the program is ill-formed, and a diagnostic will be issued.
There is no other option. (However, if size_t were void, then the
above would work because of the void* implicit conversion rules, but I
ignored that case because it's otherwise required that size_t is an
integer type.)

You miss my point. It DOES NOT MATTER to a programmer trying to write
good code whether the two types are compatible -- they should be
treated as fully distinct types anyway.

-s
 
S

Seebs

Put another way: Intention is important to understanding code. I don't
dispute that. However, some lone dude's intention when using the
standard is irrelevant when discussing technical definitions of a
technical standard.

This is a non-sequitur.

We are talking about the intention of a programmer as relevant to whether
we should view a typedef'd name as a new type even though it may be an
alias for some other type.

From the standpoint of someone hoping to write maintainable code, the
answer is "yes" -- you should treat each typedef as though it were an
incompatible type.

I don't think I've ever seen code which would be broken if the C
standard suddenly declared that typedefs were incompatible with the types
with which they wer synonymous, unless it was already conceptually
broken.

-s
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,218
Latest member
GracieDebo

Latest Threads

Top