3

I do not understand why the gnu C compiler uses 2 different macros with almost similar names -- __PTRDIFF_TYPE__ and ptrdiff_t -- , as time as they are identical as semantics.

The definition of these macros is here.

I asked a similar question concerning this issue.

I duplicate the question because in my first post I did not receive an answer I really need.

Can somebody clearly explain in detail how the gnu C compiler uses each of them ?

EDIT:

The purpose of this post is to understand how gcc concretely uses this object (pointer difference type) from the moment when the lexeme stream is generated and inserted in the parser to the moment when the semantic check is finished and IC is generated.

Community
  • 1
  • 1
alinsoar
  • 15,386
  • 4
  • 57
  • 74
  • 2
    Possible duplicate of [default value of \_\_PTRDIFF\_TYPE\_\_](http://stackoverflow.com/questions/37912580/default-value-of-ptrdiff-type). The accepted answer links to the page which explains it, I don't see the need to repeat the same question. *These macros are defined to the correct underlying types (...) [and] exist to make the standard header files `stddef.h`, `stdint.h`, and `wchar.h` work correctly. You should not use these macros directly.* – vgru Jun 25 '16 at 19:11
  • @Groo: The question is different and the answer should be posted on _this_ site, not as a link to an external site. – Nisse Engström Jun 25 '16 at 19:49
  • When I asked the question I actually wanted to ask _this_ question, but I was not able to formulate from the beginning what I wanted to know. – alinsoar Jun 25 '16 at 20:39
  • I see many `close` demands ; please close the other question, not this one. – alinsoar Jun 25 '16 at 21:14

1 Answers1

10

ptrdiff_t is not a macro, it is a typedef name, defined by stddef.h. It is specified in the C standard as the type of the difference between two pointers.

__PTRDIFF_TYPE__ is an implementation detail of GCC's stddef.h. You should not use it unless you are writing a C runtime library.

The reason both exist is that the C compiler is not allowed to define ptrdiff_t unconditionally. That name only acquires its standard-specified meaning if you include stddef.h; it's available for application use otherwise. (Note that unlike C++, in C the standard library headers are not allowed to [behave as-if they] include each other.) __PTRDIFF_TYPE__, on the other hand, is a name that the compiler is allowed to define unconditionally, because it begins with two underscores. So __PTRDIFF_TYPE__ is predefined unconditionally, and stddef.h uses it to define ptrdiff_t when appropriate.

And the reason stddef.h goes through this indirection, rather than having a bare

typedef long int ptrdiff_t;  /* or whatever */

is because the definition might need to vary depending on compilation mode. For instance, on x86-64/Linux, ptrdiff_t is long int in the default mode but int in -m32 mode. The compiler has to know which integer type to use for the difference of two pointers, so it may as well expose that information rather than making stddef.h repeat all the same logic.

(The GCC documentation you cited is quite clear on this, provided you read the entire paragraph:

These macros are defined to the correct underlying types for [a bunch of standard-specified typedef names]. They exist to make the standard header files stddef.h, stdint.h, and wchar.h work correctly. You should not use these macros directly; instead, include the appropriate headers and use the typedefs.

Emphasis mine.)

zwol
  • 135,547
  • 38
  • 252
  • 361
  • I did not answer you last night as I was working and wanted to read it carefully. Do you think, `` it's because__PTRDIFF_TYPE__`` is used by gcc internally during compilation it was necessary to define that object 2 times ? Can you describe how these objects are used from the moment the user runs `gcc` until the moment when gcc produces lexemes involving the same object ? I think there are a few hierachical levels when the same object , say PTRDIFF_TYPE is used either internally or in the generated tokens. How many redefinitions of the same thing may appear during compilation ... – alinsoar Jun 26 '16 at 09:08
  • 1
    I'm sorry, your follow-up question doesn't make any sense to me, I think because I know so intimately how this works that I can't imagine where you're getting confused. `__PTRDIFF_TYPE__` is *not* used internally. It's *defined* internally and used by `stddef.h`. Also, `__PTRDIFF_TYPE__`, `ptrdiff_t`, and the internal representation of the type used for the difference of two pointers are three different objects whose only connection is that two of them refer to the third. Can you please try to rephrase your follow-up question keeping those things in mind? – zwol Jun 26 '16 at 11:44
  • OK. Rephrase. I have to say that my purpose is to clearly understand step by step how a C compiler (as gcc) needs variables like this one to process data. Let us take another C compiler that does the same job as gcc. Namely, tcc. TCC defines the __PTRDIFF_TYPE__ in libtcc.c via ``tcc_define_symbol(s, "__PTRDIFF_TYPE__", "long long");``. My question is: why TCC defines this variable internally ? Why did not it use a variable with other name as time as it's internal ? Suppose that internally TCC used a similar variable with other name. Then, what tcc could not have been able to do? – alinsoar Jun 26 '16 at 12:30
  • I think I will accept your answer, but before to accept it I need to ponder some more days because the subject really interest me and maybe to ask more questions to clarify it. – alinsoar Jun 26 '16 at 12:32
  • tcc almost certainly uses that name so that it can reuse GCC's `stddef.h`. The authors of tcc could have picked a different name, but then they would have had to write their own `stddef.h`. If you have access to an MSVC installation, read _their_ `stddef.h` and you will see that it is completely different. – zwol Jun 26 '16 at 12:36
  • Nice; I will answer your a few more questions these days, as time as my idea clafies, please do not answer as comment any more, but edit your message as time as the ideas clarifies such that the global answer to be easy to read. – alinsoar Jun 26 '16 at 13:09
  • As I said, I know so intimately how this works that it's hard for me to understand where you're coming from. If you want me to revise the answer instead of talking to you in the comments, please point out specific aspects of the existing text that do not make sense or don't address the exact thing you wanted to know, and indicate exactly why. Right now I do not see any way to improve upon what I already wrote. – zwol Jun 26 '16 at 13:21
  • No, for now it is perfect. I am working with this and I will surely find other questions. Please stay tuned. – alinsoar Jun 26 '16 at 13:24
  • You have the patience of a saint, zwol. – Dietrich Epp Jun 26 '16 at 13:30
  • I accepted your answer, but please stay tuned for some more questions. thanks. – alinsoar Jun 26 '16 at 14:09
  • In order to avoid type checker, probably because gcc needs it at an earlier stage, it reads PTRDIFF_TYPE from elsewhere. `Elsewhere` could mean a file of the type arch.conf and `arch` is set with an option such as `-output-arch=xxx`, passed to the compiler. How exactly happens this to be set ? Is it set via config.h or some .conf file ? – alinsoar Jun 27 '16 at 12:30
  • This is the point at which you _really_ need to read the GCC internals manual, https://gcc.gnu.org/onlinedocs/gccint/ . The specific thing you're asking about is documented in https://gcc.gnu.org/onlinedocs/gccint/Type-Layout.html but unless you read the *whole manual* it's not going to make much sense. And I'd strongly recommend having a copy of the source tree open in another window (especially gcc/config/$ARCH - pick an $ARCH that you already know the assembly language for). – zwol Jun 27 '16 at 14:04
  • And, again, further questions are best taken to `gcc@gcc.gnu.org`. – zwol Jun 27 '16 at 14:04
  • good, nice. Thanks :). As I said you, I am interested about the `internals` of the C language, not about the internals of gcc, but understanding it or any other implementation it is exactly what I need. – alinsoar Jun 27 '16 at 14:42