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

J

Jon

Joshua said:
There is only one perspective: what the language standard says.

That is incorrect. While the standard says *what*, the compiler/language
implementor determines *how*.
The
language standard says that a typedef does not define a new type,
typedef never defines types, and so typedef is a misnomer. typedef
defines and/or declares type /names/, but it does not define /types/.

So why tell that to me when I've been harping that for days? I'm the one
who originally posted that 'typedef' should have been "alias" or such.
This is not the real world. Your definitions of the real world are
inapplicable. All that matters is how the language standard defines
the terms. Please reread:

You're not listening.
 
J

Jon

Joshua said:
Again, in the C language:

Names are declared. Generally, to use a name, that name must be in
scope. (Excepting the evil known as K&R C.) To bring a name into
scope, you use a declaration.

Things have definitions. You can define a function, a type, a macro,
and so on. There is more to a function than its name; it has a body,
return type, parameter types, and so on. Most things have exactly one
definition (made more formal with C++'s One Definition Rule), but they
may have multiple declarations. Definitions tend to introduce a name
for the thing just defined, so most definitions tend to be
declarations.

As such, it is perfectly sensible and consistent to use "#define" to
define a macro. It is a definition; it tells the preprocessor
everything you possibly can about the macro, enough to "use" it in
every way. It's also a declaration; it associates a name with a
particular definition.

I don't see any reason to drag yet another diversion into this subthread,
so enough about preprocessor #defines for me. (Can you say "eye on the
ball?").
 
J

Jon

Ben said:
You must have missed the part where I agreed with that. About five
messages ago.


No, there's no point in discussing it if you read my comments about
one thing (the value of #define Alias typedef) as being about
something else (some imagined stance about what typedef does) nor if
you miss or ignore the parts where I agree with you.

The value of "#define Alias typedef" is confirmed in part by this
loooooooong subthread where half the people still think a typedef
introduces a new type. Shielding someone from the confusion that is in a
soon to be deprecated language (and more people are in that group than
know it) is prudent. You, OTOH, keep spewing the same generality which is
no generality at all except in-the-box of C. Programming != just C.
 
J

Jon

Ben said:
That's a draft of a future standard so it has all sorts of changes
that are not yet implemented (in fact, they are not yet formally C).

What a great place, then, to clear up (maybe) any confusion in the
earlier *draft*. FWIW, without detailed comparison, it appears to be
worded the same in both drafts for the areas in question.
 
B

Ben Bacarisse

Jon said:
Joshua Maurice wrote:

It's not a definition. It's an *incomplete* type declaration.
('incomplete' modifies 'declaration').

The word "incomplete" has a specific meaning in C and you can't tell
without more context whether "struct bar" is or is not an incomplete
type.

You many have been using the word in some other way but (a) that's going
to be confusing since the word has a technical meaning related to types
and (b) the ordinary meaning on "incomplete" does not seem to apply here
either.
It declares a type with the identifier 'foo'.

It declares a tag 'foo'. The tag is an identifier, but its rather
misleading to say that the type (which is "struct foo") has the
identifier 'foo'. It's different in C++, of course, where this really
does name the type 'foo'.
No, it declares a typedef name 'foo2'.

It's a declaration that defines a name (a typedef name). That the way I
say it based on the language used by the standard, but I am not that
bothered by the exact terminology. What is the difference that you are
trying to draw out here? What is it about "introduces a new type name"
that makes you answer with a "no"? It seems like a perfectly reasonable
way to express what it happening.
It doesn't.

Yes, formally it is a declaration that defines a typedef name.
That just declares a type. It doesn't define one.

That is the correct use of the terms, but what value is there in making
this distinction? What problems will thinking of this declaration as
"defining a type" lead to? The original argument about typedef stemmed
from the possibility of confusion. You yourself said that some people
might think (erroneously) that a typedef makes a new type so it's
important to know what it really does (it introduces a synonym). But
the struct declaration above really does introduce a new type, so it
seems to me quite harmless (and also natural) to say that it defines a
type.

<snip>
 
K

Keith Thompson

Seebs said:
I don't think it could have. Because, back when the type system was being
worked out, I don't think char was a distinct type from the signed/unsigned
variant it was the same as.

Ok, but weren't int and long distinct types even if they were the same
size? I'm not sure just when typedef was added, but I would think that
the idea that two types with identical characteristics could
nevertheless be distinct already existed.
Now, it could have been changed by C99, as
char sort of was,

How was char changed by C99?
but I don't think people would have much wanted that.

Quite possibly. I would have, but I came to C from a background of more
strongly typed languages.
The real problem is that there are some times when you clearly want that,
and other times when you clearly don't.

Agreed. For example, Ada has subtypes (which, in some cases, act like
C's typedef) and derived types (which create a new type from an existing
one). Both are useful.
I have not yet seen any. I'd have been mildly surprised to encounter one,
although with the world as broad as it is, the chances are probably about
fifty-fifty that there's at least one profesionally-paid C programmer who
sincerely believes that typedef is a kind of a fish.

Much of the discussion in this thread seemed to me to strongly
imply that typedef creates a new type, or at least that the fact
that it doesn't is utterly unimportant.
 
K

Keith Thompson

Joshua Maurice said:
Hmm. I am defeated on a minor point, apparently in C you can define
identifiers. Most unfortunate. However, it's still relatively clear
that typedef does not define types.

No, it's clear that typedef does not *create* types. Whether it
"defines" types depends on the meaning of the word "define".
It's not at all clear that "define" means "create", at least as
the C standard uses the word "define".
 
B

Ben Bacarisse

Jon said:
The value of "#define Alias typedef" is confirmed in part by this
loooooooong subthread where half the people still think a typedef
introduces a new type. Shielding someone from the confusion that is in a
soon to be deprecated language (and more people are in that group than
know it) is prudent.

It's simple to explain what typedef does. I don't think anyone here is
actually confused about what it does. The argument has all been about
how appropriate words and phrases are when talking out what it does.
You, OTOH, keep spewing the same generality which is
no generality at all except in-the-box of C. Programming != just C.

I've made several points and they were specific and distinct.
 
R

Rui Maciel

Felix said:
How the *** do you people come to the conclusion that it wasn't given
its name quite intentionally? Someone made a mistake, huh?

Really, it is named after the task a programmer probably wants to
accomplish by using it. That's not that hard to understand and the name
just perfectly expresses the intention.

Not quite. As others have said before, the typedef construct does not create a type. It is
implemented "for syntactic convenience only". Yet, the name does expresses the intention, but not
the one some people (the majority) expect it to have. The typedef construct does not define a new
type but it does specify a type definition to be attributed to an identifier. To put it in other
words, a typedef construct sets the type definition of a certain identifier. This makes all the
sense in the world. The other interpretation (i.e., typedef creates a new type) may, in practice,
boil down to the same thing but the mechanisms involved are completely different.

Sure you can complain that this doesn't exactly match C language
grammar. As someone in this thread pointed out (I forgot where exactly,
this thread just got huge), there are probably historical reasons for
that.

Not quite. As I stated above, typedef is used to define the type that is attributed to an
identifier. It may be an historical reason (i.e., it's quite old) but not in the sense that
meanwhile C somehow evolved in such a way that the name lost its' meaning.

<snip/>


Rui Maciel
 
R

Rui Maciel

Richard said:
Of course it does. It's why its called TYPE DEF == typedef ....

No, a typedef attributes a type definition to an identifier. You can call it typedef, alias,
synonym, A.K.A. or other clever name but the concept is still the same: it defines an identifier
that refers to a specific type.


Rui Maciel
 
B

Ben Bacarisse

Keith Thompson said:
Ok, but weren't int and long distinct types even if they were the same
size? I'm not sure just when typedef was added, but I would think that
the idea that two types with identical characteristics could
nevertheless be distinct already existed.

typedef was there by the time K&R was first published. By then, int and
long were certainly "distinct" types but I don't think that mattered.
On systems where int and long where the same size you could pass an int
where a long was expected and it would all work and you'd get no
messages about it. So if typedef had been defined so as to introduce a
genuinely new and distinct type, it would be making a distinction that
did not exist between, say, int and long.

In K&R C, all that really matters about an integer type is the
representation. Conversions between integer types were all defined to
truncate bits or to extend bits as needed. There was no notion of
compatible types. I've even seen code like this:

pick_apart(hi, low)
short hi, low;
{
....
}
...
long l = ...;
pick_apart(l);

The original C Reference Manual has nothing to say about how arguments
passed may or may not match up with parameters declared.

<snip>
 
R

Rui Maciel

Jon said:
But that is compiler-level knowledge (language/compiler implementation)
and not at the software programming (programmer) level.

That doesn't make sense. Understanding and knowing that a specific identifier is a synonym of a
type instead of being a completely new type is clearly not "compiler-level knowledge". It is, in
fact, one of the most basic aspects of this language which is fundamental to the understanding of
how this programming language works. If a C programmer doesn't understand this then he will not
understand C's typing system, which is a sure way to stay incompetent as a C programmer.


Rui Maciel
 
K

Keith Thompson

Ben Bacarisse said:
typedef was there by the time K&R was first published. By then, int and
long were certainly "distinct" types but I don't think that mattered.
On systems where int and long where the same size you could pass an int
where a long was expected and it would all work and you'd get no
messages about it. So if typedef had been defined so as to introduce a
genuinely new and distinct type, it would be making a distinction that
did not exist between, say, int and long.

In K&R C, all that really matters about an integer type is the
representation. Conversions between integer types were all defined to
truncate bits or to extend bits as needed. There was no notion of
compatible types.

Even in modern C, numeric types are implicitly converted. The fact that
int and long are incompatible shows up when you have pointers to them.
For example:

int *ip = NULL;
long *lp;
lp = ip; /* constraint violation */

But I suppose in K&R C, pointer types were implicitly converted as
freely as integer types.
I've even seen code like this:

pick_apart(hi, low)
short hi, low;
{
....
}
...
long l = ...;
pick_apart(l);

Right, but the argument types weren't part of the function type, so
there was no requirement to diagnose the call as an error. Even in
modern C, non-prototype function declarations are still legal, and the
above code's behavior is undefined, but it could easily work as expected
(or blow up spectactularly).
The original C Reference Manual has nothing to say about how arguments
passed may or may not match up with parameters declared.

<snip>

I suppose the type system in K&R C, or pre-K&R C, might not have been
defined rigorously enough for the idea of two types being distinct but
otherwise identical to make sense. (I'm thinking in particular of
pre-K&R C as it existed just before typedef was introduced.)
 
S

Seebs

How was char changed by C99?

Ack, I meant C89. I think C89 is where we got the formalization that char
was a distinct type from both signed and unsigned.
Much of the discussion in this thread seemed to me to strongly
imply that typedef creates a new type, or at least that the fact
that it doesn't is utterly unimportant.

I think I'd draw the line differently.

I'd say that the real dispute is whether "creates a new type" implies that
that new type is distinct from existing types. I don't think it does, in C.

And this may come back to your observation that you came here from more
strongly typed languages. I don't expect a new type to necessarily be
distinct from other types, in C, because that hasn't been how the existing
types work. I view size_t as a type, and I'm quite aware that it is very
rare that it's distinct from both unsigned int and unsigned long in real
implementations.

-s
 
R

Rui Maciel

Jon said:
"define a type": create an instance of type. "define a function": type
the function body. The C definition(s) of 'define' should probably be
deprecated.

You don't know what you are talking about. Definitions and declarations are two different things:
the former consists of a formal statement that precisely specifies the implementation while the
latter consists of an announcement that something exists, without specifying the implementation.

So, a programmer *does* declare and define types

A definition is also a declaration but a declaration, if it doesn't specify any details regarding
the implementation, is not a definition. From the C standard, in 6.7 Declarations:

<quote>
5
A declaration speciï¬es the interpretation and attributes of a set of identiï¬ers. A deï¬nition
of an identiï¬er is a declaration for that identiï¬er that:
— for an object, causes storage to be reserved for that object;
— for a function, includes the function body;
— for an enumeration constant or typedef name, is the (only) declaration of the
identiï¬er.
</quote>

If you have trouble understanding this issue I suggest you read the following article:

http://en.wikipedia.org/wiki/Forward_declaration




Rui Maciel
 
K

Keith Thompson

Seebs said:
Ack, I meant C89. I think C89 is where we got the formalization that char
was a distinct type from both signed and unsigned.


I think I'd draw the line differently.

I'd say that the real dispute is whether "creates a new type" implies that
that new type is distinct from existing types. I don't think it does, in C.

Then in what sense is it either "created" or "a new type"?

The only way I can make that make any sense is if you apply the
word "type" to the *name* of a type. As we've discussed, I don't;
the distinction between a name and the thing the name refers to is
particularly important in discussions like this one.

Again, typedef creates a new name for an existing type; it does not
create a new type (unless you mangle the meaning of "create", "new",
and/or "type").
And this may come back to your observation that you came here from more
strongly typed languages. I don't expect a new type to necessarily be
distinct from other types, in C, because that hasn't been how the existing
types work. I view size_t as a type, and I'm quite aware that it is very
rare that it's distinct from both unsigned int and unsigned long in real
implementations.

Assume that size_t is a typedef for unsigned int.

Then I'd say that size_t is a type, and unsigned int is a type,
but they're *the same type*. If a type isn't distinct from other
types, then there's nothing new about it.

My wife chose to change her last name when we got married. This did
not create (or even "define") a new person, merely a new name for
an existing person. (If she's a new person, it's only figuratively.)
 
K

Keith Thompson

Rui Maciel said:
You don't know what you are talking about. Definitions and declarations are two different things:
the former consists of a formal statement that precisely specifies the implementation while the
latter consists of an announcement that something exists, without specifying the implementation.

I've killfiled Jon, so I don't have the full context, but the fragment
you quoted makes some sense (depending on what "create an instance of
type" means).

Personally, I accept the Standard's definition of the word "definition",
but I find it somewhat incoherent. I would have preferred that a
"definition" be a declaration that creates the entity being declared.

This is the case for functions (a function definition creates the
function, whereas a function declaration (which is not also a
definition) does not) and for objects (where "create" in that case means
"reservers storage"). But a struct declaration such as "struct foo {
int i; };" is not a definition as the standard uses the term, even
though it does create the type.
A definition is also a declaration but a declaration, if it doesn't specify any details regarding
the implementation, is not a definition. From the C standard, in 6.7 Declarations:

<quote>
5
A declaration speciï¬es the interpretation and attributes of a set of identiï¬ers. A deï¬nition
of an identiï¬er is a declaration for that identiï¬er that:
— for an object, causes storage to be reserved for that object;
— for a function, includes the function body;
— for an enumeration constant or typedef name, is the (only) declaration of the
identiï¬er.
</quote>

If you have trouble understanding this issue I suggest you read the following article:

http://en.wikipedia.org/wiki/Forward_declaration

I see nothing in what you quoted that indicates Jon doesn't understand
this.

Incidentally, whatever method you're using to copy-and-paste quotes
from the standard is messing up "fi" sequences. Apparently it's
treating "fi" as a ligature rather than as two letters, and my
newsreader doesn't render them properly; I see "speci es" and
"identi er" rather than "specifies" and "identifier". I'm not sure
what to suggest to fix this.
 
S

Seebs

Then in what sense is it either "created" or "a new type"?

Before it happens, "foo x;" is not a valid declaration, because foo doesn't
denote a type. After it happens, "foo x;" is a valid declaration, because
foo denotes a type. There was no type denoted by "foo" previously.
The only way I can make that make any sense is if you apply the
word "type" to the *name* of a type. As we've discussed, I don't;
the distinction between a name and the thing the name refers to is
particularly important in discussions like this one.

It seems less important to me, because "creates a new type which happens
to be the same as an existing type" seems sensical to me. It's just as
accurate to model it as "two types, which happen to be identical and/or
interchangeable", as it is to model it as "two names, for a single type".
Assume that size_t is a typedef for unsigned int.
Then I'd say that size_t is a type, and unsigned int is a type,
but they're *the same type*. If a type isn't distinct from other
types, then there's nothing new about it.

I'd say that they are two types, which happen to be the same. It's a new
thing, it just happens to be identical to an old thing. Here's the thing.
Once you've got all your headers included, then size_t is a type, and
unsigned int is a type, and they happen to be the same type.

But before that typedef was hit, size_t was not a type. The size_t type
has come into existence -- even though it's just a reference to another
type.

The distinction is in the name, because a type is not just a way of
representing data, but a mapping from a name to a representation of data.

Okay, jump over to UNIX for a moment:
$ echo "foo" > a
$ ln a b

The "ln" command here has created a link, not a file, but it's definitely
created a thing, and the thing it created turns out to have the same exact
semantics as the thing created by the first command, which definitely
created a new file. (Assume there wasn't already a file named a or b.)

Sure, it's actually creating a link, not a new file, but the effect is the
same as though it created a file -- you have a thing which is not distinct
in any way from a file, which is no less a file than the other thing, and
so on.

I think that's where some of this distinction comes from. I view an alias
as clearly a second-class citizen; more like a symbolic link than like a
hard link. You can tell that the alias is really not the same as the thing
it's an alias for. But, so far as I can tell, a typedef, once def'd, is
a full-fledged type which works like any other type name, so it's more like
a hard link.
My wife chose to change her last name when we got married. This did
not create (or even "define") a new person, merely a new name for
an existing person. (If she's a new person, it's only figuratively.)

This actually came up once in a game of Botticelli (the local name for
the game where you give initials and people try to guess who you're talking
about by asking yes/no questions). I gave the initials that one of our
friends would have in about two weeks... Now, the question is, was that
person alive? Fictional? Hypothetical?

I would argue that this action created a new *identity*, and I would view
types as more like identities than like people.

-s
 
J

Joshua Maurice

I've killfiled Jon, so I don't have the full context, but the fragment
you quoted makes some sense (depending on what "create an instance of
type" means).

Personally, I accept the Standard's definition of the word "definition",
but I find it somewhat incoherent.  I would have preferred that a
"definition" be a declaration that creates the entity being declared.

This is the case for functions (a function definition creates the
function, whereas a function declaration (which is not also a
definition) does not) and for objects (where "create" in that case means
"reservers storage").  But a struct declaration such as "struct foo {
int i; };" is not a definition as the standard uses the term, even
though it does create the type.

Indeed. I can only assume that this is an oversight. I will admit that
the standard does not fully back me up on this point. (I just got a
chance to read it.) The best I have is in
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf
6.7.2.3 Tags / 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.

So, the type isn't defined, but the content is. Under this definition
of terms, a typedef does not define types because nothing defines
types. Rather unsatisfying, but we can still claim that typedef is a
misnomer under these definitions of terms.

I believe that the standard's intent is pretty clear. It's what Rui
Maciel has said in the above quote: a declaration gives a name to a
thing without necessarily fully specifying the implementation or
reserving storage, and a definition reserves storage if necessary and
fully specifies the implementation - it "creates" it.
 

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

Members online

No members online now.

Forum statistics

Threads
474,093
Messages
2,570,610
Members
47,230
Latest member
RenaldoDut

Latest Threads

Top