8

I see occasional questions such as "what's the difference between a declaration and a definition":

What is the difference between a definition and a declaration? The distinction is important and intellectually it achieves two important things:

  1. It brings to the fore the difference between reference and referent
  2. It's how C enables separation in time of the attachment between reference and referent.

So why is a C typedef declaration not called a typedef definition?

Firstly, it's obviously a definition. It defines an alias. The new name is to be taken as referring to the existing thing. But it certainly binds the reference to a specific referent and is without doubt a defining statement.

Secondly, wouldn't it be called a typedec if it were a declaration?

Thirdly, wouldn't it avoid all those confusing questions people ask when they try and make a forward declaration using a typedef?

Community
  • 1
  • 1
Persixty
  • 6,693
  • 2
  • 10
  • 31
  • 5
    Are you prepared to accept the possibility that the answer may be as simple as "the standard is not 100% consistent in its terminology"? – Oliver Charlesworth Nov 19 '14 at 20:25
  • 1
    A typedef declaration is both a definition *and* a declaration. I imagine that people usually refer to them as "declarations" instead of definitions because the latter sounds redundant. – John Bollinger Nov 19 '14 at 20:26
  • And FWIW, the exact language from the standard is as follows: "*In a declaration whose storage-class specifier is `typedef`, each declarator defines an identifier to be a `typedef` name that denotes the type specified for the identifier*". – Oliver Charlesworth Nov 19 '14 at 20:26
  • Oliver Charleswoth, I suppose I am. I still think there's real epiphany in understanding that I'm right and that it unlocks understanding to realise it. The hardest thing people struggle with in C is pointers and pointers to pointers and pointers to pointer to pointers and so on. When you start to think about references and referents you've got it. Also I notice novice Java programmers who haven't cut their teeth on C take an age to 'get' references and objects because they haven't had this exact box opened to them and shown how the magic works inside. – Persixty Nov 19 '14 at 20:29
  • 1
    Pointers are hard. I'm not sure what that has to do with typedefs or declarations/definitions, though... – Oliver Charlesworth Nov 19 '14 at 20:31
  • 1
    I think it's mealy mouthed to say it's both and misses the goodies. All definitions are declarative. But the important distinction people draw is declarations that are pure declarations and ones that are definitions. – Persixty Nov 19 '14 at 20:33
  • Oliver, It has everything to do with pointers. The artful way C allows you to play with references (pointers) and referents (memory/code) is closely coupled (intellectually) with the distinction between declarations (of references) and definitions (their coupling to referents). – Persixty Nov 19 '14 at 20:40
  • That's quite an abstraction. It may make sense from a language-theoretical point-of-view (or type algebra or whatever), though I'm not qualified to comment. What I can say is that this is not something that 99% of C programmers would ever think about, so unlikely to be at the root of helping them understand pointers... – Oliver Charlesworth Nov 19 '14 at 20:43
  • I don't understand the downvote. Also, refreshing to see someone with a low-score ask an exceptionally esoteric C question. +1 – RLH Nov 19 '14 at 20:50
  • The following goes directly against the definition in the link... `struct foo;/*predeclare foo*/typedef struct foo bar;/*valid, compiles*//*bar x; //Error Storage size of bar isn't known*/bar* pointer_to_bar;/*this is fine*/` Since we don't know the `sizeof(bar)`, the compiler doesn't know what it needs to make a reference to bar. And thus, it is a declaration, not a definition. Semantics tho :-P – IdeaHat Nov 19 '14 at 20:53
  • 2
    The C standard in fact defines the terms "definition" and "declaration", including as they pertain to `typedefs`. I was a bit loose when I earlier wrote that they are the same for `typedef`s: I should have said "according to the C89 standard, every `typedef` declaration is also a definition". Later standards relax that: only the first declaration of a given `typedef` name is a definition of it. Since in that sense some typedef declarations indeed are not definitions, it is perfectly appropriate to use the term "declaration" (which always applies). – John Bollinger Nov 19 '14 at 20:56
  • @RLH: I downvoted based on the original form of the question, which was more of an ideological diatribe. In its current form, it's better, but I still question the pragmatic value; the definitions (apologies for the overloaded term) of concepts in the standard are what they are; they don't affect the functionality of any code that gets written. – Oliver Charlesworth Nov 20 '14 at 00:20
  • They don't affect functionality but it's clear to me that this wrong foots and confuses novices. The consistent use of terms and concepts makes an enormous contribution to clarity. – Persixty Nov 20 '14 at 00:25

1 Answers1

4

A typedef declaration is a definition.

N1570 6.7p5:

A declaration specifies the interpretation and attributes of a set of identifiers. A definition of an identifier is a declaration for that identifier that:

  • for an object, causes storage to be reserved for that object;
  • for a function, includes the function body;
  • for an enumeration constant, is the (only) declaration of the identifier;
  • for a typedef name, is the first (or only) declaration of the identifier.

In C99, the last two bullet points were combined; C11 introduced the ability to declare the same typedef twice.

Note that only objects, functions, enumeration constants, and typedef names can have definitions. One might argue that given:

enum foo { zero, one};

it doesn't make much sense to consider this to be a definition of zero and one, but not of foo or enum foo. On the other hand, an enum, struct, or union declaration, though it creates a type that didn't previously exist, doesn't define an identifier that is that type's name -- and for structs and union, the tag name can be used (as an incomplete type) even before the type has been defined. Definitions define identifiers, not (necessarily) the entities to which they refer.

As for why it's not called a "definition" in the subsection that defines it, it's part of section 6.7 "Declarations", which covers all kinds of declarations (some of which are also definitions). The term definition is defined in the introductory part of 6.7.

As for the name typedef, it's caused a fair amount of confusion over the years since it doesn't really define a type. Perhaps typename would have been a better choice, or even typealias. But since it does define the identifier, typedef isn't entirely misleading.

Keith Thompson
  • 230,326
  • 38
  • 368
  • 578
  • Agreed. It is a definition. I'm pointing out it ought be called a typedef definition on the basis of (as you point out) it being a definition. ;) It's a strange anomaly in plain sight and I hadn't noticed for 20 years. – Persixty Nov 19 '14 at 22:14
  • @DanAllen: I added a couple of paragraphs to the end of my answer just as you were posting your comment. – Keith Thompson Nov 19 '14 at 22:27
  • Keith, I think I said elsewhere it does define. It defines an alias. But I accept your notioned alternatives are all good. Based on the (useful) common distinction given to people who ask "what's the difference" defining something to be the same as something else is a definition. Just not the definition of something entirely new! No one has yet argued it's a declaration (except I think in the sense that all definitions are declarative). I think we're violently agreeing. That's a good thing. – Persixty Nov 19 '14 at 22:39
  • 1
    @Dan, No, the *first* declaration of a given typedef name in a given translation unit is a definition. In C11 and later, the same name can be (identically) redeclared, in which case the second and subsequent declarations are **only** declarations, not definitions. – John Bollinger Nov 19 '14 at 22:46
  • John, Nice argument. Upvoted accordingly. I will argue that it's not a declaration but repetition of the definition. But I think you've made the best reply yet. – Persixty Nov 19 '14 at 23:00
  • @JohnBollinger: Right. But since the rule permitting redeclarations was introduced in C11, it doesn't explain why typedefs were referred to as declarations rather than definitions in the first place. But my updated answer tries to address that. – Keith Thompson Nov 19 '14 at 23:00
  • Keith, Thanks for the exacting dissection of the historical standards. This question is even more entertaining that I imagined. – Persixty Nov 19 '14 at 23:11
  • @Dan as far as the standard is concerned, no object can have more than one definition (though some -- not typedefs -- can have declarations but zero definitions). You can call typedef redeclarations "definitions" if you like, but then you are using personal jargon, not the terminology of the standard. I am not going to argue with you about why your personal jargon may or may not be consistent. – John Bollinger Nov 19 '14 at 23:19
  • John, I'm not really putting up a serious objection. That's why I said it was best answer yet. However in the general linguistic sense I don't think a repeated definition is necessarily a declaration. I did point out in the original version of the question that there are some (I think massively) important intellectual aspects to the distinction. – Persixty Nov 19 '14 at 23:41