pid_t (and similar types) - why, just why?











up vote
40
down vote

favorite
7












What's the logic behind calls like getpid() returning a value of type pid_t instead of an unsigned int? Or int? How does this help?



I'm guessing this has to do with portability? Guaranteeing that pid_t is the same size across different platforms that may have different sizes of ints etc.?










share|improve this question


























    up vote
    40
    down vote

    favorite
    7












    What's the logic behind calls like getpid() returning a value of type pid_t instead of an unsigned int? Or int? How does this help?



    I'm guessing this has to do with portability? Guaranteeing that pid_t is the same size across different platforms that may have different sizes of ints etc.?










    share|improve this question
























      up vote
      40
      down vote

      favorite
      7









      up vote
      40
      down vote

      favorite
      7






      7





      What's the logic behind calls like getpid() returning a value of type pid_t instead of an unsigned int? Or int? How does this help?



      I'm guessing this has to do with portability? Guaranteeing that pid_t is the same size across different platforms that may have different sizes of ints etc.?










      share|improve this question













      What's the logic behind calls like getpid() returning a value of type pid_t instead of an unsigned int? Or int? How does this help?



      I'm guessing this has to do with portability? Guaranteeing that pid_t is the same size across different platforms that may have different sizes of ints etc.?







      c






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Sep 11 '11 at 14:25









      ntl0ve

      89421225




      89421225
























          6 Answers
          6






          active

          oldest

          votes

















          up vote
          37
          down vote



          accepted










          I think it's the opposite: making the program portable across platforms, regardless of whether, e.g., a PID is 16 or 32 bits (or even longer).






          share|improve this answer

















          • 4




            Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
            – zzz777
            Aug 8 '17 at 12:40










          • @zzz777 Oh god, so true...
            – Ivan
            Jan 14 at 23:28


















          up vote
          30
          down vote













          The reason is to allow nasty historical implementations to still be conformant. Suppose your historical implementation had (rather common):



          short getpid(void);


          Of course modern systems want pids to be at least 32-bit, but if the standard mandated:



          int getpid(void);


          then all historical implementations that had used short would become non-conformant. This was deemed unacceptable, so pid_t was created and the implementation was allowed to define pid_t whichever way it prefers.



          Note that you are by no means obligated to use pid_t in your own code as long as you use a type that's large enough to store any pid (intmax_t for example would work just fine). The only reason pid_t needs to exist is for the standard to define getpid, waitpid, etc. in terms of it.






          share|improve this answer





















          • Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
            – ntl0ve
            Sep 11 '11 at 14:53






          • 1




            If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
            – Prof. Falken
            Sep 11 '11 at 14:53










          • Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
            – R..
            Sep 11 '11 at 15:17






          • 3




            A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
            – R..
            Sep 11 '11 at 15:18


















          up vote
          9
          down vote













          On different platforms and operating systems, different types (pid_t for example) might be 32 bits (unsigned int) on a 32-bit machine or 64 bits (unsigned long) on a 64-bit machine. Or, for some other reason, an operating system might choose to have a different size. Additionally, it makes it clear when reading the code that this variable represents an "object", rather than just an arbitrary number.






          share|improve this answer

















          • 2




            fork() returns -1 on failure, so pid_t has to be signed integer type.
            – Przemek
            Jun 17 at 19:56


















          up vote
          6
          down vote













          The purpose of it is to make pid_t, or any other type of the sort, platform-independent, such that it works properly regardless of how it's actually implemented. This practice is used for any type that needs to be platform-independent, such as:





          • pid_t: Has to be large enough to store a PID on the system you're coding for. Maps to int as far as I'm aware, although I'm not the most familiar with the GNU C library.


          • size_t: An unsigned variable able to store the result of the sizeof operator. Generally equal in size to the word size of the system you're coding for.


          • int16_t (intX_t): Has to be exactly 16 bits, regardless of platform, and won't be defined on platforms that don't use 2n-bit bytes (typically 8- or 16-bit) or, much less frequently, provide a means of accessing exactly 16 bits out of a larger type (e.g., the PDP-10's "bytes", which could be any number of contiguous bits out of a 36-bit word, and thus could be exactly 16 bits), and thus don't support 16-bit two's complement integer types (such as a 36-bit system). Generally maps to short on modern computers, although it may be an int on older ones.


          • int_least32_t (int_leastX_t): Has to be the smallest size possible that can store at least 32 bits, such as 36 bits on a 36-bit or 72-bit system. Generally maps to int on modern computers, although it may be a long on older ones.


          • int_fastX_t: Has to be the fastest type possible that can store at least X bits. Generally, it's the system's word size if (X <= word_size) (or sometimes char for int_fast8_t), or acts like int_leastX_t if (X > word_size))


          • intmax_t: Has to be the maximum integer width supported by the system. Generally, it'll be at least 64 bits on modern systems, although some systems may support extended types larger than long long (and if so, intmax_t is required to be the largest of those types).

          • And more...


          Mechanically, it allows the compiler's installer to typedef the appropriate type to the identifier (whether a standard type or an awkwardly-named internal type) behind the scenes, whether by creating appropriate header files, coding it into the compiler's executable, or some other method. For example, on a 32-bit system, Microsoft Visual Studio will implement the intX_t and similar types as follows (note: comments added by me):



          // Signed ints of exactly X bits.
          typedef signed char int8_t;
          typedef short int16_t;
          typedef int int32_t;

          // Unsigned ints of exactly X bits.
          typedef unsigned char uint8_t;
          typedef unsigned short uint16_t;
          typedef unsigned int uint32_t;

          // Signed ints of at least X bits.
          typedef signed char int_least8_t;
          typedef short int_least16_t;
          typedef int int_least32_t;

          // Unsigned ints of at least X bits.
          typedef unsigned char uint_least8_t;
          typedef unsigned short uint_least16_t;
          typedef unsigned int uint_least32_t;

          // Speed-optimised signed ints of at least X bits.
          // Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
          typedef char int_fast8_t;
          typedef int int_fast16_t;
          typedef int int_fast32_t;

          // Speed-optimised unsigned ints of at least X bits.
          typedef unsigned char uint_fast8_t;
          typedef unsigned int uint_fast16_t;
          typedef unsigned int uint_fast32_t;

          typedef _Longlong int64_t;
          typedef _ULonglong uint64_t;

          typedef _Longlong int_least64_t;
          typedef _ULonglong uint_least64_t;

          typedef _Longlong int_fast64_t;
          typedef _ULonglong uint_fast64_t;


          On a 64-bit system, however, they may not necessarily be implemented the same way, and I can guarantee that they won't be implemented the same way on an archaic 16-bit system, assuming you can find a version of MSVS compatible with one.



          Overall, it allows code to work properly regardless of the specifics of your implementation, and to meet the same requirements on any standards-compatible system (e.g. pid_t can be guaranteed to be large enough to hold any valid PID on the system in question, no matter what system you're coding for). It also prevents you from having to know the nitty-gritty, and from having to look up internal names you may not be familiar with. In short, it makes sure your code works the same regardless of whether pid_t (or any other similar typedef) is implemented as an int, a short, a long, a long long, or even a __Did_you_really_just_dare_me_to_eat_my_left_shoe__, so you don't have to.





          Additionally, it serves as a form of documentation, allowing you to tell what a given variable is for at a glance. Consider the following:



          int a, b;

          ....

          if (a > b) {
          // Nothing wrong here, right? They're both ints.
          }


          Now, let's try that again:



          size_t a;
          pid_t b;

          ...

          if (a > b) {
          // Why are we comparing sizes to PIDs? We probably messed up somewhere.
          }


          If used as such, it can help you locate potentially problematic segments of code before anything breaks, and can make troubleshooting much easier than it would otherwise be.






          share|improve this answer























          • "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
            – Antti Haapala
            Nov 12 at 6:22










          • I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
            – Justin Time
            Nov 14 at 23:04












          • The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
            – Antti Haapala
            Nov 14 at 23:16










          • I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
            – Justin Time
            Nov 26 at 22:51










          • Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
            – Justin Time
            Nov 26 at 23:03


















          up vote
          2
          down vote













          Each process in the program has a specific process ID. By calling pid, we know the assigned ID of the current process.Knowing the pid is exceptionally important when we use fork(), because it returns 0 and !=0 values for child and parent copies receptively.These two videos have clear explanations: video#1 Video#2



          An example: Suppose we have the following c program:



          #include <stdio.h>
          #include <stdlib.h>
          #include <sys/types.h>
          #include <unistd.h>


          int main (int argc, char *argv)
          {

          printf("I am %dn", (int) getpid());
          pid_t pid = fork();
          printf("fork returned: %dn", (int) pid);
          if(pid<0){
          perror("fork failed");
          }
          if (pid==0){
          printf("This is a child with pid %dn",(int) getpid());
          }else if(pid >0){
          printf("This is a parent with pid %dn",(int)getpid());
          }

          return 0;
          }


          If you run it, you will get 0 for child and non zero/greater than zero for the parent.






          share|improve this answer






























            up vote
            0
            down vote













            One thing to point out, in most answers I saw something along the lines of
            "using pid_t makes the code work on different systems", which is not necessarily true.



            I believe the precise wording should be: it makes the code 'compile' on different systems.



            As, for instance, compiling the code on a system that uses 32-bit pid_t will produce a binary that will probably break if run on another system that uses 64-bit pid_t.






            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7378854%2fpid-t-and-similar-types-why-just-why%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              6 Answers
              6






              active

              oldest

              votes








              6 Answers
              6






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              37
              down vote



              accepted










              I think it's the opposite: making the program portable across platforms, regardless of whether, e.g., a PID is 16 or 32 bits (or even longer).






              share|improve this answer

















              • 4




                Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
                – zzz777
                Aug 8 '17 at 12:40










              • @zzz777 Oh god, so true...
                – Ivan
                Jan 14 at 23:28















              up vote
              37
              down vote



              accepted










              I think it's the opposite: making the program portable across platforms, regardless of whether, e.g., a PID is 16 or 32 bits (or even longer).






              share|improve this answer

















              • 4




                Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
                – zzz777
                Aug 8 '17 at 12:40










              • @zzz777 Oh god, so true...
                – Ivan
                Jan 14 at 23:28













              up vote
              37
              down vote



              accepted







              up vote
              37
              down vote



              accepted






              I think it's the opposite: making the program portable across platforms, regardless of whether, e.g., a PID is 16 or 32 bits (or even longer).






              share|improve this answer












              I think it's the opposite: making the program portable across platforms, regardless of whether, e.g., a PID is 16 or 32 bits (or even longer).







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Sep 11 '11 at 14:30









              zvrba

              20.7k34663




              20.7k34663








              • 4




                Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
                – zzz777
                Aug 8 '17 at 12:40










              • @zzz777 Oh god, so true...
                – Ivan
                Jan 14 at 23:28














              • 4




                Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
                – zzz777
                Aug 8 '17 at 12:40










              • @zzz777 Oh god, so true...
                – Ivan
                Jan 14 at 23:28








              4




              4




              Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
              – zzz777
              Aug 8 '17 at 12:40




              Sub-typing integers beyond xiint8_t xint16_t xint32_t xint64_t does not solve any problems: there are automatic integer conversions in place. Hence each and every real world program of reasonable age (say 10 years) and size (say 1MLOC) contains 1000s of undetectable silent assumptions about integer sizes.
              – zzz777
              Aug 8 '17 at 12:40












              @zzz777 Oh god, so true...
              – Ivan
              Jan 14 at 23:28




              @zzz777 Oh god, so true...
              – Ivan
              Jan 14 at 23:28












              up vote
              30
              down vote













              The reason is to allow nasty historical implementations to still be conformant. Suppose your historical implementation had (rather common):



              short getpid(void);


              Of course modern systems want pids to be at least 32-bit, but if the standard mandated:



              int getpid(void);


              then all historical implementations that had used short would become non-conformant. This was deemed unacceptable, so pid_t was created and the implementation was allowed to define pid_t whichever way it prefers.



              Note that you are by no means obligated to use pid_t in your own code as long as you use a type that's large enough to store any pid (intmax_t for example would work just fine). The only reason pid_t needs to exist is for the standard to define getpid, waitpid, etc. in terms of it.






              share|improve this answer





















              • Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
                – ntl0ve
                Sep 11 '11 at 14:53






              • 1




                If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
                – Prof. Falken
                Sep 11 '11 at 14:53










              • Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
                – R..
                Sep 11 '11 at 15:17






              • 3




                A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
                – R..
                Sep 11 '11 at 15:18















              up vote
              30
              down vote













              The reason is to allow nasty historical implementations to still be conformant. Suppose your historical implementation had (rather common):



              short getpid(void);


              Of course modern systems want pids to be at least 32-bit, but if the standard mandated:



              int getpid(void);


              then all historical implementations that had used short would become non-conformant. This was deemed unacceptable, so pid_t was created and the implementation was allowed to define pid_t whichever way it prefers.



              Note that you are by no means obligated to use pid_t in your own code as long as you use a type that's large enough to store any pid (intmax_t for example would work just fine). The only reason pid_t needs to exist is for the standard to define getpid, waitpid, etc. in terms of it.






              share|improve this answer





















              • Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
                – ntl0ve
                Sep 11 '11 at 14:53






              • 1




                If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
                – Prof. Falken
                Sep 11 '11 at 14:53










              • Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
                – R..
                Sep 11 '11 at 15:17






              • 3




                A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
                – R..
                Sep 11 '11 at 15:18













              up vote
              30
              down vote










              up vote
              30
              down vote









              The reason is to allow nasty historical implementations to still be conformant. Suppose your historical implementation had (rather common):



              short getpid(void);


              Of course modern systems want pids to be at least 32-bit, but if the standard mandated:



              int getpid(void);


              then all historical implementations that had used short would become non-conformant. This was deemed unacceptable, so pid_t was created and the implementation was allowed to define pid_t whichever way it prefers.



              Note that you are by no means obligated to use pid_t in your own code as long as you use a type that's large enough to store any pid (intmax_t for example would work just fine). The only reason pid_t needs to exist is for the standard to define getpid, waitpid, etc. in terms of it.






              share|improve this answer












              The reason is to allow nasty historical implementations to still be conformant. Suppose your historical implementation had (rather common):



              short getpid(void);


              Of course modern systems want pids to be at least 32-bit, but if the standard mandated:



              int getpid(void);


              then all historical implementations that had used short would become non-conformant. This was deemed unacceptable, so pid_t was created and the implementation was allowed to define pid_t whichever way it prefers.



              Note that you are by no means obligated to use pid_t in your own code as long as you use a type that's large enough to store any pid (intmax_t for example would work just fine). The only reason pid_t needs to exist is for the standard to define getpid, waitpid, etc. in terms of it.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Sep 11 '11 at 14:45









              R..

              154k26254560




              154k26254560












              • Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
                – ntl0ve
                Sep 11 '11 at 14:53






              • 1




                If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
                – Prof. Falken
                Sep 11 '11 at 14:53










              • Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
                – R..
                Sep 11 '11 at 15:17






              • 3




                A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
                – R..
                Sep 11 '11 at 15:18


















              • Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
                – ntl0ve
                Sep 11 '11 at 14:53






              • 1




                If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
                – Prof. Falken
                Sep 11 '11 at 14:53










              • Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
                – R..
                Sep 11 '11 at 15:17






              • 3




                A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
                – R..
                Sep 11 '11 at 15:18
















              Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
              – ntl0ve
              Sep 11 '11 at 14:53




              Ah, standards. Got it. But what about style/best practice? Is it better to use pid_t than an int for holding a pid? Readability-wise (alluding to @Maz answer)? Or is it such a trivial and meaningless thing that it doesn't deserve this kind of attention?
              – ntl0ve
              Sep 11 '11 at 14:53




              1




              1




              If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
              – Prof. Falken
              Sep 11 '11 at 14:53




              If I could double vote... but zvrbas answer is kind of the compressed version of this answer, so I'll upvote zvrba too.
              – Prof. Falken
              Sep 11 '11 at 14:53












              Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
              – R..
              Sep 11 '11 at 15:17




              Using int is probably not a good idea since it would not support hypothetical future implementations with 64-bit pids. I would just use pid_t for most uses, but keep in mind that if you have a data structure that can store "generic integers" with a large type (i.e. intmax_t) it would be acceptable to store pids that way.
              – R..
              Sep 11 '11 at 15:17




              3




              3




              A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
              – R..
              Sep 11 '11 at 15:18




              A better example of a "useless" type would be socklen_t which was added for the same reason (disagreement over whether certain functions should take int or size_t arguments).
              – R..
              Sep 11 '11 at 15:18










              up vote
              9
              down vote













              On different platforms and operating systems, different types (pid_t for example) might be 32 bits (unsigned int) on a 32-bit machine or 64 bits (unsigned long) on a 64-bit machine. Or, for some other reason, an operating system might choose to have a different size. Additionally, it makes it clear when reading the code that this variable represents an "object", rather than just an arbitrary number.






              share|improve this answer

















              • 2




                fork() returns -1 on failure, so pid_t has to be signed integer type.
                – Przemek
                Jun 17 at 19:56















              up vote
              9
              down vote













              On different platforms and operating systems, different types (pid_t for example) might be 32 bits (unsigned int) on a 32-bit machine or 64 bits (unsigned long) on a 64-bit machine. Or, for some other reason, an operating system might choose to have a different size. Additionally, it makes it clear when reading the code that this variable represents an "object", rather than just an arbitrary number.






              share|improve this answer

















              • 2




                fork() returns -1 on failure, so pid_t has to be signed integer type.
                – Przemek
                Jun 17 at 19:56













              up vote
              9
              down vote










              up vote
              9
              down vote









              On different platforms and operating systems, different types (pid_t for example) might be 32 bits (unsigned int) on a 32-bit machine or 64 bits (unsigned long) on a 64-bit machine. Or, for some other reason, an operating system might choose to have a different size. Additionally, it makes it clear when reading the code that this variable represents an "object", rather than just an arbitrary number.






              share|improve this answer












              On different platforms and operating systems, different types (pid_t for example) might be 32 bits (unsigned int) on a 32-bit machine or 64 bits (unsigned long) on a 64-bit machine. Or, for some other reason, an operating system might choose to have a different size. Additionally, it makes it clear when reading the code that this variable represents an "object", rather than just an arbitrary number.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Sep 11 '11 at 14:30









              Maz

              2,9111727




              2,9111727








              • 2




                fork() returns -1 on failure, so pid_t has to be signed integer type.
                – Przemek
                Jun 17 at 19:56














              • 2




                fork() returns -1 on failure, so pid_t has to be signed integer type.
                – Przemek
                Jun 17 at 19:56








              2




              2




              fork() returns -1 on failure, so pid_t has to be signed integer type.
              – Przemek
              Jun 17 at 19:56




              fork() returns -1 on failure, so pid_t has to be signed integer type.
              – Przemek
              Jun 17 at 19:56










              up vote
              6
              down vote













              The purpose of it is to make pid_t, or any other type of the sort, platform-independent, such that it works properly regardless of how it's actually implemented. This practice is used for any type that needs to be platform-independent, such as:





              • pid_t: Has to be large enough to store a PID on the system you're coding for. Maps to int as far as I'm aware, although I'm not the most familiar with the GNU C library.


              • size_t: An unsigned variable able to store the result of the sizeof operator. Generally equal in size to the word size of the system you're coding for.


              • int16_t (intX_t): Has to be exactly 16 bits, regardless of platform, and won't be defined on platforms that don't use 2n-bit bytes (typically 8- or 16-bit) or, much less frequently, provide a means of accessing exactly 16 bits out of a larger type (e.g., the PDP-10's "bytes", which could be any number of contiguous bits out of a 36-bit word, and thus could be exactly 16 bits), and thus don't support 16-bit two's complement integer types (such as a 36-bit system). Generally maps to short on modern computers, although it may be an int on older ones.


              • int_least32_t (int_leastX_t): Has to be the smallest size possible that can store at least 32 bits, such as 36 bits on a 36-bit or 72-bit system. Generally maps to int on modern computers, although it may be a long on older ones.


              • int_fastX_t: Has to be the fastest type possible that can store at least X bits. Generally, it's the system's word size if (X <= word_size) (or sometimes char for int_fast8_t), or acts like int_leastX_t if (X > word_size))


              • intmax_t: Has to be the maximum integer width supported by the system. Generally, it'll be at least 64 bits on modern systems, although some systems may support extended types larger than long long (and if so, intmax_t is required to be the largest of those types).

              • And more...


              Mechanically, it allows the compiler's installer to typedef the appropriate type to the identifier (whether a standard type or an awkwardly-named internal type) behind the scenes, whether by creating appropriate header files, coding it into the compiler's executable, or some other method. For example, on a 32-bit system, Microsoft Visual Studio will implement the intX_t and similar types as follows (note: comments added by me):



              // Signed ints of exactly X bits.
              typedef signed char int8_t;
              typedef short int16_t;
              typedef int int32_t;

              // Unsigned ints of exactly X bits.
              typedef unsigned char uint8_t;
              typedef unsigned short uint16_t;
              typedef unsigned int uint32_t;

              // Signed ints of at least X bits.
              typedef signed char int_least8_t;
              typedef short int_least16_t;
              typedef int int_least32_t;

              // Unsigned ints of at least X bits.
              typedef unsigned char uint_least8_t;
              typedef unsigned short uint_least16_t;
              typedef unsigned int uint_least32_t;

              // Speed-optimised signed ints of at least X bits.
              // Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
              typedef char int_fast8_t;
              typedef int int_fast16_t;
              typedef int int_fast32_t;

              // Speed-optimised unsigned ints of at least X bits.
              typedef unsigned char uint_fast8_t;
              typedef unsigned int uint_fast16_t;
              typedef unsigned int uint_fast32_t;

              typedef _Longlong int64_t;
              typedef _ULonglong uint64_t;

              typedef _Longlong int_least64_t;
              typedef _ULonglong uint_least64_t;

              typedef _Longlong int_fast64_t;
              typedef _ULonglong uint_fast64_t;


              On a 64-bit system, however, they may not necessarily be implemented the same way, and I can guarantee that they won't be implemented the same way on an archaic 16-bit system, assuming you can find a version of MSVS compatible with one.



              Overall, it allows code to work properly regardless of the specifics of your implementation, and to meet the same requirements on any standards-compatible system (e.g. pid_t can be guaranteed to be large enough to hold any valid PID on the system in question, no matter what system you're coding for). It also prevents you from having to know the nitty-gritty, and from having to look up internal names you may not be familiar with. In short, it makes sure your code works the same regardless of whether pid_t (or any other similar typedef) is implemented as an int, a short, a long, a long long, or even a __Did_you_really_just_dare_me_to_eat_my_left_shoe__, so you don't have to.





              Additionally, it serves as a form of documentation, allowing you to tell what a given variable is for at a glance. Consider the following:



              int a, b;

              ....

              if (a > b) {
              // Nothing wrong here, right? They're both ints.
              }


              Now, let's try that again:



              size_t a;
              pid_t b;

              ...

              if (a > b) {
              // Why are we comparing sizes to PIDs? We probably messed up somewhere.
              }


              If used as such, it can help you locate potentially problematic segments of code before anything breaks, and can make troubleshooting much easier than it would otherwise be.






              share|improve this answer























              • "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
                – Antti Haapala
                Nov 12 at 6:22










              • I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
                – Justin Time
                Nov 14 at 23:04












              • The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
                – Antti Haapala
                Nov 14 at 23:16










              • I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
                – Justin Time
                Nov 26 at 22:51










              • Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
                – Justin Time
                Nov 26 at 23:03















              up vote
              6
              down vote













              The purpose of it is to make pid_t, or any other type of the sort, platform-independent, such that it works properly regardless of how it's actually implemented. This practice is used for any type that needs to be platform-independent, such as:





              • pid_t: Has to be large enough to store a PID on the system you're coding for. Maps to int as far as I'm aware, although I'm not the most familiar with the GNU C library.


              • size_t: An unsigned variable able to store the result of the sizeof operator. Generally equal in size to the word size of the system you're coding for.


              • int16_t (intX_t): Has to be exactly 16 bits, regardless of platform, and won't be defined on platforms that don't use 2n-bit bytes (typically 8- or 16-bit) or, much less frequently, provide a means of accessing exactly 16 bits out of a larger type (e.g., the PDP-10's "bytes", which could be any number of contiguous bits out of a 36-bit word, and thus could be exactly 16 bits), and thus don't support 16-bit two's complement integer types (such as a 36-bit system). Generally maps to short on modern computers, although it may be an int on older ones.


              • int_least32_t (int_leastX_t): Has to be the smallest size possible that can store at least 32 bits, such as 36 bits on a 36-bit or 72-bit system. Generally maps to int on modern computers, although it may be a long on older ones.


              • int_fastX_t: Has to be the fastest type possible that can store at least X bits. Generally, it's the system's word size if (X <= word_size) (or sometimes char for int_fast8_t), or acts like int_leastX_t if (X > word_size))


              • intmax_t: Has to be the maximum integer width supported by the system. Generally, it'll be at least 64 bits on modern systems, although some systems may support extended types larger than long long (and if so, intmax_t is required to be the largest of those types).

              • And more...


              Mechanically, it allows the compiler's installer to typedef the appropriate type to the identifier (whether a standard type or an awkwardly-named internal type) behind the scenes, whether by creating appropriate header files, coding it into the compiler's executable, or some other method. For example, on a 32-bit system, Microsoft Visual Studio will implement the intX_t and similar types as follows (note: comments added by me):



              // Signed ints of exactly X bits.
              typedef signed char int8_t;
              typedef short int16_t;
              typedef int int32_t;

              // Unsigned ints of exactly X bits.
              typedef unsigned char uint8_t;
              typedef unsigned short uint16_t;
              typedef unsigned int uint32_t;

              // Signed ints of at least X bits.
              typedef signed char int_least8_t;
              typedef short int_least16_t;
              typedef int int_least32_t;

              // Unsigned ints of at least X bits.
              typedef unsigned char uint_least8_t;
              typedef unsigned short uint_least16_t;
              typedef unsigned int uint_least32_t;

              // Speed-optimised signed ints of at least X bits.
              // Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
              typedef char int_fast8_t;
              typedef int int_fast16_t;
              typedef int int_fast32_t;

              // Speed-optimised unsigned ints of at least X bits.
              typedef unsigned char uint_fast8_t;
              typedef unsigned int uint_fast16_t;
              typedef unsigned int uint_fast32_t;

              typedef _Longlong int64_t;
              typedef _ULonglong uint64_t;

              typedef _Longlong int_least64_t;
              typedef _ULonglong uint_least64_t;

              typedef _Longlong int_fast64_t;
              typedef _ULonglong uint_fast64_t;


              On a 64-bit system, however, they may not necessarily be implemented the same way, and I can guarantee that they won't be implemented the same way on an archaic 16-bit system, assuming you can find a version of MSVS compatible with one.



              Overall, it allows code to work properly regardless of the specifics of your implementation, and to meet the same requirements on any standards-compatible system (e.g. pid_t can be guaranteed to be large enough to hold any valid PID on the system in question, no matter what system you're coding for). It also prevents you from having to know the nitty-gritty, and from having to look up internal names you may not be familiar with. In short, it makes sure your code works the same regardless of whether pid_t (or any other similar typedef) is implemented as an int, a short, a long, a long long, or even a __Did_you_really_just_dare_me_to_eat_my_left_shoe__, so you don't have to.





              Additionally, it serves as a form of documentation, allowing you to tell what a given variable is for at a glance. Consider the following:



              int a, b;

              ....

              if (a > b) {
              // Nothing wrong here, right? They're both ints.
              }


              Now, let's try that again:



              size_t a;
              pid_t b;

              ...

              if (a > b) {
              // Why are we comparing sizes to PIDs? We probably messed up somewhere.
              }


              If used as such, it can help you locate potentially problematic segments of code before anything breaks, and can make troubleshooting much easier than it would otherwise be.






              share|improve this answer























              • "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
                – Antti Haapala
                Nov 12 at 6:22










              • I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
                – Justin Time
                Nov 14 at 23:04












              • The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
                – Antti Haapala
                Nov 14 at 23:16










              • I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
                – Justin Time
                Nov 26 at 22:51










              • Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
                – Justin Time
                Nov 26 at 23:03













              up vote
              6
              down vote










              up vote
              6
              down vote









              The purpose of it is to make pid_t, or any other type of the sort, platform-independent, such that it works properly regardless of how it's actually implemented. This practice is used for any type that needs to be platform-independent, such as:





              • pid_t: Has to be large enough to store a PID on the system you're coding for. Maps to int as far as I'm aware, although I'm not the most familiar with the GNU C library.


              • size_t: An unsigned variable able to store the result of the sizeof operator. Generally equal in size to the word size of the system you're coding for.


              • int16_t (intX_t): Has to be exactly 16 bits, regardless of platform, and won't be defined on platforms that don't use 2n-bit bytes (typically 8- or 16-bit) or, much less frequently, provide a means of accessing exactly 16 bits out of a larger type (e.g., the PDP-10's "bytes", which could be any number of contiguous bits out of a 36-bit word, and thus could be exactly 16 bits), and thus don't support 16-bit two's complement integer types (such as a 36-bit system). Generally maps to short on modern computers, although it may be an int on older ones.


              • int_least32_t (int_leastX_t): Has to be the smallest size possible that can store at least 32 bits, such as 36 bits on a 36-bit or 72-bit system. Generally maps to int on modern computers, although it may be a long on older ones.


              • int_fastX_t: Has to be the fastest type possible that can store at least X bits. Generally, it's the system's word size if (X <= word_size) (or sometimes char for int_fast8_t), or acts like int_leastX_t if (X > word_size))


              • intmax_t: Has to be the maximum integer width supported by the system. Generally, it'll be at least 64 bits on modern systems, although some systems may support extended types larger than long long (and if so, intmax_t is required to be the largest of those types).

              • And more...


              Mechanically, it allows the compiler's installer to typedef the appropriate type to the identifier (whether a standard type or an awkwardly-named internal type) behind the scenes, whether by creating appropriate header files, coding it into the compiler's executable, or some other method. For example, on a 32-bit system, Microsoft Visual Studio will implement the intX_t and similar types as follows (note: comments added by me):



              // Signed ints of exactly X bits.
              typedef signed char int8_t;
              typedef short int16_t;
              typedef int int32_t;

              // Unsigned ints of exactly X bits.
              typedef unsigned char uint8_t;
              typedef unsigned short uint16_t;
              typedef unsigned int uint32_t;

              // Signed ints of at least X bits.
              typedef signed char int_least8_t;
              typedef short int_least16_t;
              typedef int int_least32_t;

              // Unsigned ints of at least X bits.
              typedef unsigned char uint_least8_t;
              typedef unsigned short uint_least16_t;
              typedef unsigned int uint_least32_t;

              // Speed-optimised signed ints of at least X bits.
              // Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
              typedef char int_fast8_t;
              typedef int int_fast16_t;
              typedef int int_fast32_t;

              // Speed-optimised unsigned ints of at least X bits.
              typedef unsigned char uint_fast8_t;
              typedef unsigned int uint_fast16_t;
              typedef unsigned int uint_fast32_t;

              typedef _Longlong int64_t;
              typedef _ULonglong uint64_t;

              typedef _Longlong int_least64_t;
              typedef _ULonglong uint_least64_t;

              typedef _Longlong int_fast64_t;
              typedef _ULonglong uint_fast64_t;


              On a 64-bit system, however, they may not necessarily be implemented the same way, and I can guarantee that they won't be implemented the same way on an archaic 16-bit system, assuming you can find a version of MSVS compatible with one.



              Overall, it allows code to work properly regardless of the specifics of your implementation, and to meet the same requirements on any standards-compatible system (e.g. pid_t can be guaranteed to be large enough to hold any valid PID on the system in question, no matter what system you're coding for). It also prevents you from having to know the nitty-gritty, and from having to look up internal names you may not be familiar with. In short, it makes sure your code works the same regardless of whether pid_t (or any other similar typedef) is implemented as an int, a short, a long, a long long, or even a __Did_you_really_just_dare_me_to_eat_my_left_shoe__, so you don't have to.





              Additionally, it serves as a form of documentation, allowing you to tell what a given variable is for at a glance. Consider the following:



              int a, b;

              ....

              if (a > b) {
              // Nothing wrong here, right? They're both ints.
              }


              Now, let's try that again:



              size_t a;
              pid_t b;

              ...

              if (a > b) {
              // Why are we comparing sizes to PIDs? We probably messed up somewhere.
              }


              If used as such, it can help you locate potentially problematic segments of code before anything breaks, and can make troubleshooting much easier than it would otherwise be.






              share|improve this answer














              The purpose of it is to make pid_t, or any other type of the sort, platform-independent, such that it works properly regardless of how it's actually implemented. This practice is used for any type that needs to be platform-independent, such as:





              • pid_t: Has to be large enough to store a PID on the system you're coding for. Maps to int as far as I'm aware, although I'm not the most familiar with the GNU C library.


              • size_t: An unsigned variable able to store the result of the sizeof operator. Generally equal in size to the word size of the system you're coding for.


              • int16_t (intX_t): Has to be exactly 16 bits, regardless of platform, and won't be defined on platforms that don't use 2n-bit bytes (typically 8- or 16-bit) or, much less frequently, provide a means of accessing exactly 16 bits out of a larger type (e.g., the PDP-10's "bytes", which could be any number of contiguous bits out of a 36-bit word, and thus could be exactly 16 bits), and thus don't support 16-bit two's complement integer types (such as a 36-bit system). Generally maps to short on modern computers, although it may be an int on older ones.


              • int_least32_t (int_leastX_t): Has to be the smallest size possible that can store at least 32 bits, such as 36 bits on a 36-bit or 72-bit system. Generally maps to int on modern computers, although it may be a long on older ones.


              • int_fastX_t: Has to be the fastest type possible that can store at least X bits. Generally, it's the system's word size if (X <= word_size) (or sometimes char for int_fast8_t), or acts like int_leastX_t if (X > word_size))


              • intmax_t: Has to be the maximum integer width supported by the system. Generally, it'll be at least 64 bits on modern systems, although some systems may support extended types larger than long long (and if so, intmax_t is required to be the largest of those types).

              • And more...


              Mechanically, it allows the compiler's installer to typedef the appropriate type to the identifier (whether a standard type or an awkwardly-named internal type) behind the scenes, whether by creating appropriate header files, coding it into the compiler's executable, or some other method. For example, on a 32-bit system, Microsoft Visual Studio will implement the intX_t and similar types as follows (note: comments added by me):



              // Signed ints of exactly X bits.
              typedef signed char int8_t;
              typedef short int16_t;
              typedef int int32_t;

              // Unsigned ints of exactly X bits.
              typedef unsigned char uint8_t;
              typedef unsigned short uint16_t;
              typedef unsigned int uint32_t;

              // Signed ints of at least X bits.
              typedef signed char int_least8_t;
              typedef short int_least16_t;
              typedef int int_least32_t;

              // Unsigned ints of at least X bits.
              typedef unsigned char uint_least8_t;
              typedef unsigned short uint_least16_t;
              typedef unsigned int uint_least32_t;

              // Speed-optimised signed ints of at least X bits.
              // Note that int_fast16_t and int_fast32_t are both 32 bits, as a 32-bit processor will generally operate on a full word faster than a half-word.
              typedef char int_fast8_t;
              typedef int int_fast16_t;
              typedef int int_fast32_t;

              // Speed-optimised unsigned ints of at least X bits.
              typedef unsigned char uint_fast8_t;
              typedef unsigned int uint_fast16_t;
              typedef unsigned int uint_fast32_t;

              typedef _Longlong int64_t;
              typedef _ULonglong uint64_t;

              typedef _Longlong int_least64_t;
              typedef _ULonglong uint_least64_t;

              typedef _Longlong int_fast64_t;
              typedef _ULonglong uint_fast64_t;


              On a 64-bit system, however, they may not necessarily be implemented the same way, and I can guarantee that they won't be implemented the same way on an archaic 16-bit system, assuming you can find a version of MSVS compatible with one.



              Overall, it allows code to work properly regardless of the specifics of your implementation, and to meet the same requirements on any standards-compatible system (e.g. pid_t can be guaranteed to be large enough to hold any valid PID on the system in question, no matter what system you're coding for). It also prevents you from having to know the nitty-gritty, and from having to look up internal names you may not be familiar with. In short, it makes sure your code works the same regardless of whether pid_t (or any other similar typedef) is implemented as an int, a short, a long, a long long, or even a __Did_you_really_just_dare_me_to_eat_my_left_shoe__, so you don't have to.





              Additionally, it serves as a form of documentation, allowing you to tell what a given variable is for at a glance. Consider the following:



              int a, b;

              ....

              if (a > b) {
              // Nothing wrong here, right? They're both ints.
              }


              Now, let's try that again:



              size_t a;
              pid_t b;

              ...

              if (a > b) {
              // Why are we comparing sizes to PIDs? We probably messed up somewhere.
              }


              If used as such, it can help you locate potentially problematic segments of code before anything breaks, and can make troubleshooting much easier than it would otherwise be.







              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 26 at 23:01

























              answered Jan 22 '16 at 3:11









              Justin Time

              3,0021329




              3,0021329












              • "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
                – Antti Haapala
                Nov 12 at 6:22










              • I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
                – Justin Time
                Nov 14 at 23:04












              • The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
                – Antti Haapala
                Nov 14 at 23:16










              • I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
                – Justin Time
                Nov 26 at 22:51










              • Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
                – Justin Time
                Nov 26 at 23:03


















              • "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
                – Antti Haapala
                Nov 12 at 6:22










              • I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
                – Justin Time
                Nov 14 at 23:04












              • The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
                – Antti Haapala
                Nov 14 at 23:16










              • I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
                – Justin Time
                Nov 26 at 22:51










              • Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
                – Justin Time
                Nov 26 at 23:03
















              "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
              – Antti Haapala
              Nov 12 at 6:22




              "byte" == char in C. byte can be 16 bits, and int16_t can then exist.
              – Antti Haapala
              Nov 12 at 6:22












              I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
              – Justin Time
              Nov 14 at 23:04






              I was talking about the hardware, @AnttiHaapala, not the language. Hence specifying that the type is only defined on platforms that support 8-bit bytes, as those are by extension the platforms that would allow the use of exactly-16-bit types. Note that int16_t is not defined as "the length of two chars", but as "16 bits exactly". I did forget about the 2's complement requirement, though, so thanks for that part.
              – Justin Time
              Nov 14 at 23:04














              The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
              – Antti Haapala
              Nov 14 at 23:16




              The platform in the question that I linked does not have any means for 8-bit addressing. 8 is (almost) as meaningless a number as 4 is on x86...
              – Antti Haapala
              Nov 14 at 23:16












              I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
              – Justin Time
              Nov 26 at 22:51




              I may have misread your comment then, @AnttiHaapala. Hmm... I'll make a quick edit, then.
              – Justin Time
              Nov 26 at 22:51












              Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
              – Justin Time
              Nov 26 at 23:03




              Okay, edited it in, and also accounted for another weird case I remembered (some old systems, like the PDP-10, had variable-length storage, and a byte could be anywhere from 1-36 bits (specifically, it had a 36-bit word, and any amount of contiguous bits in a single word could be accessed as a "byte")).
              – Justin Time
              Nov 26 at 23:03










              up vote
              2
              down vote













              Each process in the program has a specific process ID. By calling pid, we know the assigned ID of the current process.Knowing the pid is exceptionally important when we use fork(), because it returns 0 and !=0 values for child and parent copies receptively.These two videos have clear explanations: video#1 Video#2



              An example: Suppose we have the following c program:



              #include <stdio.h>
              #include <stdlib.h>
              #include <sys/types.h>
              #include <unistd.h>


              int main (int argc, char *argv)
              {

              printf("I am %dn", (int) getpid());
              pid_t pid = fork();
              printf("fork returned: %dn", (int) pid);
              if(pid<0){
              perror("fork failed");
              }
              if (pid==0){
              printf("This is a child with pid %dn",(int) getpid());
              }else if(pid >0){
              printf("This is a parent with pid %dn",(int)getpid());
              }

              return 0;
              }


              If you run it, you will get 0 for child and non zero/greater than zero for the parent.






              share|improve this answer



























                up vote
                2
                down vote













                Each process in the program has a specific process ID. By calling pid, we know the assigned ID of the current process.Knowing the pid is exceptionally important when we use fork(), because it returns 0 and !=0 values for child and parent copies receptively.These two videos have clear explanations: video#1 Video#2



                An example: Suppose we have the following c program:



                #include <stdio.h>
                #include <stdlib.h>
                #include <sys/types.h>
                #include <unistd.h>


                int main (int argc, char *argv)
                {

                printf("I am %dn", (int) getpid());
                pid_t pid = fork();
                printf("fork returned: %dn", (int) pid);
                if(pid<0){
                perror("fork failed");
                }
                if (pid==0){
                printf("This is a child with pid %dn",(int) getpid());
                }else if(pid >0){
                printf("This is a parent with pid %dn",(int)getpid());
                }

                return 0;
                }


                If you run it, you will get 0 for child and non zero/greater than zero for the parent.






                share|improve this answer

























                  up vote
                  2
                  down vote










                  up vote
                  2
                  down vote









                  Each process in the program has a specific process ID. By calling pid, we know the assigned ID of the current process.Knowing the pid is exceptionally important when we use fork(), because it returns 0 and !=0 values for child and parent copies receptively.These two videos have clear explanations: video#1 Video#2



                  An example: Suppose we have the following c program:



                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <sys/types.h>
                  #include <unistd.h>


                  int main (int argc, char *argv)
                  {

                  printf("I am %dn", (int) getpid());
                  pid_t pid = fork();
                  printf("fork returned: %dn", (int) pid);
                  if(pid<0){
                  perror("fork failed");
                  }
                  if (pid==0){
                  printf("This is a child with pid %dn",(int) getpid());
                  }else if(pid >0){
                  printf("This is a parent with pid %dn",(int)getpid());
                  }

                  return 0;
                  }


                  If you run it, you will get 0 for child and non zero/greater than zero for the parent.






                  share|improve this answer














                  Each process in the program has a specific process ID. By calling pid, we know the assigned ID of the current process.Knowing the pid is exceptionally important when we use fork(), because it returns 0 and !=0 values for child and parent copies receptively.These two videos have clear explanations: video#1 Video#2



                  An example: Suppose we have the following c program:



                  #include <stdio.h>
                  #include <stdlib.h>
                  #include <sys/types.h>
                  #include <unistd.h>


                  int main (int argc, char *argv)
                  {

                  printf("I am %dn", (int) getpid());
                  pid_t pid = fork();
                  printf("fork returned: %dn", (int) pid);
                  if(pid<0){
                  perror("fork failed");
                  }
                  if (pid==0){
                  printf("This is a child with pid %dn",(int) getpid());
                  }else if(pid >0){
                  printf("This is a parent with pid %dn",(int)getpid());
                  }

                  return 0;
                  }


                  If you run it, you will get 0 for child and non zero/greater than zero for the parent.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jul 16 '16 at 0:44

























                  answered Jul 16 '16 at 0:39







                  user6288471





























                      up vote
                      0
                      down vote













                      One thing to point out, in most answers I saw something along the lines of
                      "using pid_t makes the code work on different systems", which is not necessarily true.



                      I believe the precise wording should be: it makes the code 'compile' on different systems.



                      As, for instance, compiling the code on a system that uses 32-bit pid_t will produce a binary that will probably break if run on another system that uses 64-bit pid_t.






                      share|improve this answer

























                        up vote
                        0
                        down vote













                        One thing to point out, in most answers I saw something along the lines of
                        "using pid_t makes the code work on different systems", which is not necessarily true.



                        I believe the precise wording should be: it makes the code 'compile' on different systems.



                        As, for instance, compiling the code on a system that uses 32-bit pid_t will produce a binary that will probably break if run on another system that uses 64-bit pid_t.






                        share|improve this answer























                          up vote
                          0
                          down vote










                          up vote
                          0
                          down vote









                          One thing to point out, in most answers I saw something along the lines of
                          "using pid_t makes the code work on different systems", which is not necessarily true.



                          I believe the precise wording should be: it makes the code 'compile' on different systems.



                          As, for instance, compiling the code on a system that uses 32-bit pid_t will produce a binary that will probably break if run on another system that uses 64-bit pid_t.






                          share|improve this answer












                          One thing to point out, in most answers I saw something along the lines of
                          "using pid_t makes the code work on different systems", which is not necessarily true.



                          I believe the precise wording should be: it makes the code 'compile' on different systems.



                          As, for instance, compiling the code on a system that uses 32-bit pid_t will produce a binary that will probably break if run on another system that uses 64-bit pid_t.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Jan 14 at 23:25









                          0xcurb

                          816




                          816






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f7378854%2fpid-t-and-similar-types-why-just-why%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Guess what letter conforming each word

                              Port of Spain

                              Run scheduled task as local user group (not BUILTIN)