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

K

Keith Thompson

This, again, is from the C grammar or compiler view. That's the wrong
way to think about it. The 'typedef' keyword is used by programmers to
define their types and a human being will most of the time define a
thing by giving it a name. Although typedef is not the only way to do
this (struct and enum will also create a name in their special
namespaces), it is ONE possible way and for many the preferred way.
Compilers do not care about natural language semantics of a keyword,
programmers do; 'typealias' would be much less obvious.

I guess Felix won't see this, but ...

I strongly disagree that "That's the wrong way to think about it."
It's a *different* way to think about it.

A typedef creates a new name for an existing type. You can use that
new name as an abstraction, a name for a logical entity distinct
from the original type (as size_t is logically distinct from whatever
its base type is, for example).

But it's just as important to understand that the compiler doesn't
create a new type as it is to understand how to use typedef to
create a logical abstraction.

If nothing else, you need to know that if you accidentally mix your
abstraction with the type it's derived from, the compiler probably
isn't going to help you find the mistake.

For example, this program:

#include <stdio.h>
int main(void)
{
printf("stdin->_fileno = %d\n", stdin->_fileno);
printf("sizeof(int) = %u\n", sizeof(int));
return 0;
}

compiles and runs with no diagnostics on my system, because FILE
and size_t are both typedefs. The program is in some sense wrong
(or at least non-portable) but knowing why the compiler doesn't
catch the errors it requires an understanding of how typedef works
on the language level.

(Of course a compiler *could* recognize the use of typedefs and
print warnings when they're misused.)
 
S

Seebs

Yes, that's exactly what I'm doing. And personally I think it makes
sense to be consistent about the "define" vs. "declare" distinction, but
it's not really worth arguing about, as long as we understand what we
actually mean. I'll keep that in mind, and I'll probably try to avoid
using the word "define" when it's not clear what it's supposed to mean.

The problem is, we're already inconsistent about it -- #define is totally
unlike a "definition".

Come to think of it though... Does the standard actually call the thing
which reifies a struct type a "definition", or is that also a declaration?
I've seen people refer to the one that says what's in the struct as
a declaration, and the one that just says there's such a struct somewhere
as a "forward declaration".
So here's the real point. A typedef does not create a type; it merely
creates a new name for an existing type.

I agree. What it creates is a *term*. It's defining a term, not defining
a type. But the word "type" is also used, not just for the underlying
mapping of space to interpretation, but to the words used to denote them.
So it does create a word-for-a-mapping.

I think that's the other confusion; "type" is used both to refer to the
mapping of storage to meaning, and to the names we give those. "typedef"
defines a new name for a mapping of storage to a meaning. It doesn't matter
whether that mapping already had another name, or could only be spelled
out using the aggregate type mechainsms; we defined a new word for it.
Suppose a new version of the C standard added a "typecreate" keyword
that acts like typedef except that the new type is distinct from the old
one. So, for example:
struct foo { int x; };
typedef struct foo foo1;
typecreate struct foo foo2;
So struct foo and foo1 are different names for the same type, but
foo2 is a distinct type. I'd probably say that typecreate defines
a new type and typedef doesn't. You, I suppose, would say that
typecreate defines and creates a new type, whereas typedef defines
a new type but doesn't create one.

Yes. Because both of them are clearly defining a word which wasn't
previously meaningful and turning into a type -- in the sense of "a
thing which goes in the <type> slot of a declaration".

-s
 
K

Keith Thompson

BartC said:
In this syntax, end-of-line is interpreted as a semi-colon unless the last
symbol on the line was a comma. It uses \ line-continuations to join lines
as in C (and I'm briefly wandering why you need actually \ escapes in C,
outside of macros, since EOL is just white space anyway...)
[...]

Macro definitions, as you mention, are the obvious place where
line-continuations are needed.

Prior to the introduction of string literal pasting in C89, it was
also commonly needed for very long string literals.

It might also be useful in some cases for automatically generated
code, where the generator might create logical lines longer than
the maximum physical line. It might also make sense in some cases
to create extremely long identifiers.

Apart from that, you rarely *need* line continuations, but it would
be more difficult to restrict their use to cases that make sense
than to just allow them generally.
 
S

Seebs

That's a matter of opinion. Smell isn't everything.

True.

The more I think about it, the more I think the problem is that we have
multiple words which can be used in multiple senses:

* define as in "a declaration which provides an initial value is a definition"
-> let's call this "create"
* define as in "a dictionary defines words"
-> let's call this "label"

* type as in "the mapping between storage and interpretation"
-> let's call this "mapping"
* type as in "the name that denotes such a mapping"
-> let's call this "typename"

Given that, the statement "typedef defines a type" can be translated into
any of:
* typedef creates a mapping (false)
* typedef labels a mapping (true)
* typedef creates a typename (true)
* typedef labels a typename (false)

So it's true about half the time. :p I think "labels a typename" is an
incoherency in practice, so it's true of two of the three things I could
possibly mean by the original statement.

-s
 
K

Keith Thompson

Seebs said:
The problem is, we're already inconsistent about it -- #define is totally
unlike a "definition".

Really? It creates a new macro (one that didn't previously exist) and a
name for it. A macro is a very different thing than, say, an object,
but it seems reasonably consistent.
Come to think of it though... Does the standard actually call the thing
which reifies a struct type a "definition", or is that also a declaration?
I've seen people refer to the one that says what's in the struct as
a declaration, and the one that just says there's such a struct somewhere
as a "forward declaration".

The syntactic category for "struct foo { int x; }" is
"struct-or-union-specifier". (There is a "struct-declaration",
but that refers to a member declaration such as "int x;".)

A "struct-or-union-specifier" is one kind of "type-specifier",
which matches "declaration-specifiers", which matches "declaration".
I agree. What it creates is a *term*. It's defining a term, not defining
a type. But the word "type" is also used, not just for the underlying
mapping of space to interpretation, but to the words used to denote them.
So it does create a word-for-a-mapping.

I think that's the other confusion; "type" is used both to refer to the
mapping of storage to meaning, and to the names we give those. "typedef"
defines a new name for a mapping of storage to a meaning. It doesn't matter
whether that mapping already had another name, or could only be spelled
out using the aggregate type mechainsms; we defined a new word for it.

I don't entirely agree. The word "int", consisting of the letters
'i', 'n', and 't', is not a type, it's a keyword. It happens to
be the name of a type, but it is not itself a type.

When we say "int is a type", "int" doesn't refer to the syntactic
keyword, it refers to the thing that the name refers to. It's a
distinction that we can and do ignore most of the time, but in
contexts like this it can be important. It's very much like the
distiction between "numeral" and "number".
Yes. Because both of them are clearly defining a word which wasn't
previously meaningful and turning into a type -- in the sense of "a
thing which goes in the <type> slot of a declaration".

Well, turning it into *a name for* a type, but we've already gone over
that.
 
J

John Bode

Most people use the term "create a new type" to mean "create a new type".

By your logic, the dictionary does not define words.  Which, I'm sure in
your twisted mind, it doesn't (as you - or one of your socks - will no
doubt explain that to me any minute now)...

I'm not a sock, but I'll be more than happy to point out what you (and
several others) seem to be missing.

Which of the following lines of code actually *define* a new type?

struct foo {
int bar;
double bletch;
};

typedef struct foo Foo;

Hint: it's not the typedef.

Even for something like

typedef struct {
int bar;
double bletch;
} Foo;

it is the *struct definition* that *defines* a new type; the *typedef*
associates a *name* with that type.

typedef int MyInt;

associates the *name* MyInt with the existing type int.

typedef char **MyPtr;

associates the *name* MyPtr with the existing type char **.

Und so weiter.

This isn't rocket science, guys.
 
S

Seebs

Really? It creates a new macro (one that didn't previously exist) and a
name for it. A macro is a very different thing than, say, an object,
but it seems reasonably consistent.

But it doesn't create a new thing, it just creates a new spelling for an
existing block of code.
A "struct-or-union-specifier" is one kind of "type-specifier",
which matches "declaration-specifiers", which matches "declaration".

So that's a declaration, not a definition, even though it defines...
argh.
When we say "int is a type", "int" doesn't refer to the syntactic
keyword, it refers to the thing that the name refers to. It's a
distinction that we can and do ignore most of the time, but in
contexts like this it can be important. It's very much like the
distiction between "numeral" and "number".

But in:
int x;
the word "int" is commonly referred to as a type. Perhaps it shouldn't
be, but it is. Similarly, in
struct foo x;
the phrase "struct foo" is a type.
Well, turning it into *a name for* a type, but we've already gone over
that.

Yeah, but same with the macro; the macro is really just a name for the
expansion of a hunk of code which was already typed somewhere. :)

We're creating a new mapping from a name to a thing, such that the name
can now be used in places where we use types. That is an awful lot like
creating a type.

We're also giving a definition of what a given thing is, and that thing
happens to denote a type.

-s
 
J

John Bode

...




The funny thing is that I am certain that at least 90% (probably 99%) of
working C programmers have had no contact with and no knowledge of the
sacred C standards documents.  They just get their job done and go home
at 5 to their families.

And then a couple of years later people like me get called in to find
out why code that was working "perfectly" is suddenly barfing all over
the place after a system update, only to find instances of things
where the standard says, "hey, don't do that, it won't work the way
you think it will."

There's no excuse for not having at least a passing familiarity with
the DEFINITION OF THE LANGUAGE YOU ARE PROGRAMMING IN, particularly
the bits where it says "hey, don't do that." It's more of an issue
for C than for, say, Fortran, because there's so goddamned much
misinformation about C out in the wild. Couple that with the attitude
of "hurr hurr who needs to read the standard hurr" and you have the
recipe for buggy, unsafe systems.
 
A

Alan Curry

Which of the following lines of code actually *define* a new type?

struct foo {
int bar;
double bletch;
};

typedef struct foo Foo;

Hint: it's not the typedef.

Alternate interpretation: the first one creates a type and defines
"struct foo" to be a name of the new type. The second defines "Foo" to be a
name of the same type. Defining (a.k.a. naming) and creating don't need to be
done at the same time.
Even for something like

typedef struct {
int bar;
double bletch;
} Foo;

it is the *struct definition* that *defines* a new type; the *typedef*
associates a *name* with that type.

Better yet, look at this one:

struct {
int x,y,z;
} foo;

It created a type, obviously. It defined foo as an instance of that type. But
the type has no name, so has it been "defined"? Some say no. Others go so far
as to say that even with a struct tag, it still lacks a name since "real"
names must be in the global identifier namespace. Those people... have gone
too far and are addicted to unnecessary typedefs.
typedef int MyInt;

associates the *name* MyInt with the existing type int.

Associating a name with a concept/entity is what "defining" actually is.
 
J

Jon

If the goal is to leave behind and deprecate C ASAP, it's a fine
intermediary technique (they need know nothing of the define, only the
"keyword" which will be the same after transition to the good GP language
when it arrives, and it will). If the goal is to perpetuate the woefully
inadequate constructs of C (for whatever reason, see end of this post),
then it is "bad". If that is "bad" then, the descriptive adjective for
the C programming language would likely be an expletive-derived word.
I have no idea what this means, but I am not sure how much that
matters. I've expressed my view a clearly as I can and I don't think
you've misunderstood it, so there's little point in my saying more.
I may be incapable of understanding your point of view so we might as
well just leave it that we disagree about something.

Keywords should be well-thought out and reasonably understandable at
first sight. If you can't admit that "typedef" is a bad choice of keyword
because it does nothing like "define a type" (and it's really *declaring*
a type that most people think is happening) and that is what 99.9% of new
programmers and probably half of existing programmers think it does, then
there is really no point in discussing anything. Hence, I associated your
stance in a more appropriate area: religion and naivete (and if not that,
it must be politics or propaganda or job-security), and I don't play
those games.
 
J

Jon

Keith said:
I agree that "typedef" was not a good choice of name for the
semantics. Perhaps "typealias" would have been better.

But "typedef" is in the language, and it's not going away. Every C
programmer needs to understand that "typedef" doesn't define a type
(just as "const" doesn't mean constant).

Adding an obfuscating macro *does not help*, any more than
#define BEGIN {
#define END }
#define IF if (
#define THEN ) {
and so on.

That is not nearly the same thing and that you posted that really shows
that you are grasping for any little thing in some kind of attempt at
<whatever> (see the bottom of my last post for some options for
"<whatever>"). (Is what he did called "a strawman"? IOW, a lame
"argument"?).
 
J

Jon

Nick said:
Wholehearted agreement here.

Then you're as bone-headed as he is. (If you 2 are really just
cognitively-challenged, then disregard the preceding assessment).
 
J

Jon

Nick said:
terrible advice.

It wasn't advice. It is a fact, lest a programmer be afflicted
unnecesarrily with archaic notions of programming.
Look, this whole thread is a contrafactual.

The parts by "The C Rah-Rah Crowd", yes.
*if* we'd been sitting at
Dennis Ritchie's right hand when he was designing C what would we have
suggested to him?.

"alias" (or something at least something better than "typedef").
There's no suggestion that any of these changes to
C are actually real.
?


my original suggestion was "typealias" not "alias"

Which is a hundred times better than "typedef", but does seem to
introduce compound words as keywords which is probably not necessary and
probably not desireable.
 
J

Jon

Felix said:
Just try -- for a second -- to realize there is no confusion at all.
Then think about why people decided to give typedef its name. Probably
to confuse people, right?

Because they/he didn't analyze/think-about-it enough and certainly didn't
consider higher-level issues such as programmer learning. A new
programmer will have to understand this tangential thread and an
inquisitive one will go back-and-forth like you and Keith are. Is anymore
evidence needed as to why "typedef" was a bad choic? To most it is
plainly obvious that is was a bad (and even incorrect, yes, a design
flaw/defect) choice.
 
J

Jon

Keith said:
Finally, something I should have written earlier, a quote from the C
standard. C99 6.7.7p3:

A typedef declaration does not introduce a new type, only a
synonym for the type so specified.

#define synonym typedef

:)
 
N

Nick

Jon said:
Then you're as bone-headed as he is. (If you 2 are really just
cognitively-challenged, then disregard the preceding assessment).

Absolutely. Keith and I are at complete loggerheads apart from agreeing
that mangling the language is stupid. If that makes up both boneheaded
and cognitively-challenged then so be it.

Mind you, if you are defining (or is it just naming?) me in that way,
with the same style, lucidity and common sense as the rest of your
recent postings, I will treat your assessment the same way. That is,
I'll ignore it as complete gibberish.
 
J

Jon

Ben said:
Well I didn't. The passing shot (quoted above) suggests that he was
making a point, disconnected from the C language, about how one should
think about a typedef'd type. However, I don't think that was the
point he was making earlier in the thread.

At some point, I think he was doing: "typedef operates like it does,
therefore one must accept that 'typedef' has only the meaning as
exhibited by its operation and not by its coincidental likeness to any
English language word(s) or fragments thereof. That is to say, it's just
like any random glyph used for a specific operation. The glyph could be a
swastika but operate like "typedef" in C, and because it was chosen as
the glyph, it is, by nature of being chosen, appropriate and correct and
irrefutably the best choice."
 
B

Ben Bacarisse

Jon said:
Keywords should be well-thought out and reasonably understandable at
first sight. If you can't admit that "typedef" is a bad choice of
keyword

You must have missed the part where I agreed with that. About five
messages ago.
because it does nothing like "define a type" (and it's really *declaring*
a type that most people think is happening) and that is what 99.9% of new
programmers and probably half of existing programmers think it does, then
there is really no point in discussing anything.

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.
 
F

Felix Palmen

* Jon said:
Because they/he didn't analyze/think-about-it enough and certainly didn't
consider higher-level issues such as programmer learning. A new
programmer will have to understand this tangential thread and an
inquisitive one will go back-and-forth like you and Keith are. Is anymore
evidence needed as to why "typedef" was a bad choic? To most it is
plainly obvious that is was a bad (and even incorrect, yes, a design
flaw/defect) choice.

Really, compared to your random gibberish in this thread, Keith's posts
were remarkably sensible.
 

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,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top