C++ auto on int16_t casts to integer





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







17















I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto.



Below is a snippet of code that produces an unexpected result.



#include <typeinfo>
#include <iostream>
#include <algorithm>

using namespace std;

int main() {

int16_t mid = 4;
auto low = mid - static_cast<int16_t>(2);
auto hi = mid + static_cast<int16_t>(2);

int16_t val;
cin >> val;

val = std::clamp(val,low,hi);

return 0;
}


Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int. If I change auto to int16_t all is good in the world and all the types are int16_t as expected.



The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t? Is this a good use case for decltype?



Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.










share|improve this question































    17















    I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto.



    Below is a snippet of code that produces an unexpected result.



    #include <typeinfo>
    #include <iostream>
    #include <algorithm>

    using namespace std;

    int main() {

    int16_t mid = 4;
    auto low = mid - static_cast<int16_t>(2);
    auto hi = mid + static_cast<int16_t>(2);

    int16_t val;
    cin >> val;

    val = std::clamp(val,low,hi);

    return 0;
    }


    Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int. If I change auto to int16_t all is good in the world and all the types are int16_t as expected.



    The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t? Is this a good use case for decltype?



    Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.










    share|improve this question



























      17












      17








      17


      1






      I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto.



      Below is a snippet of code that produces an unexpected result.



      #include <typeinfo>
      #include <iostream>
      #include <algorithm>

      using namespace std;

      int main() {

      int16_t mid = 4;
      auto low = mid - static_cast<int16_t>(2);
      auto hi = mid + static_cast<int16_t>(2);

      int16_t val;
      cin >> val;

      val = std::clamp(val,low,hi);

      return 0;
      }


      Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int. If I change auto to int16_t all is good in the world and all the types are int16_t as expected.



      The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t? Is this a good use case for decltype?



      Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.










      share|improve this question
















      I am pretty new to C++17 and am attempting to understand the decltype keyword and how it pairs with auto.



      Below is a snippet of code that produces an unexpected result.



      #include <typeinfo>
      #include <iostream>
      #include <algorithm>

      using namespace std;

      int main() {

      int16_t mid = 4;
      auto low = mid - static_cast<int16_t>(2);
      auto hi = mid + static_cast<int16_t>(2);

      int16_t val;
      cin >> val;

      val = std::clamp(val,low,hi);

      return 0;
      }


      Surprisingly, the compiler tells me there is a mismatch in clamp and that low and high are int. If I change auto to int16_t all is good in the world and all the types are int16_t as expected.



      The question I'm posing is, why does auto cast low and hi to int when all of the types are int16_t? Is this a good use case for decltype?



      Even after reading cppreference.com, I don't fully understand how decltype works, so excuse my ignorance.







      c++ c++17 auto decltype






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Apr 12 at 5:32









      Remy Lebeau

      344k19270464




      344k19270464










      asked Apr 12 at 4:24









      MaxMax

      7491925




      7491925
























          2 Answers
          2






          active

          oldest

          votes


















          18














          The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here:



          #include <iostream>
          #include <cstdint>
          using namespace std;

          template<class T>
          void print_type(T) {
          std::cout << __PRETTY_FUNCTION__ << std::endl;
          }

          int main() {
          int16_t a = 10;
          int16_t b = 20;
          print_type(a);
          print_type(b);
          print_type(a - b);
          return 0;
          }


          a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.






          share|improve this answer































            4














            This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.






            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',
              autoActivateHeartbeat: false,
              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%2f55644479%2fc-auto-on-int16-t-casts-to-integer%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              18














              The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here:



              #include <iostream>
              #include <cstdint>
              using namespace std;

              template<class T>
              void print_type(T) {
              std::cout << __PRETTY_FUNCTION__ << std::endl;
              }

              int main() {
              int16_t a = 10;
              int16_t b = 20;
              print_type(a);
              print_type(b);
              print_type(a - b);
              return 0;
              }


              a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.






              share|improve this answer




























                18














                The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here:



                #include <iostream>
                #include <cstdint>
                using namespace std;

                template<class T>
                void print_type(T) {
                std::cout << __PRETTY_FUNCTION__ << std::endl;
                }

                int main() {
                int16_t a = 10;
                int16_t b = 20;
                print_type(a);
                print_type(b);
                print_type(a - b);
                return 0;
                }


                a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.






                share|improve this answer


























                  18












                  18








                  18







                  The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here:



                  #include <iostream>
                  #include <cstdint>
                  using namespace std;

                  template<class T>
                  void print_type(T) {
                  std::cout << __PRETTY_FUNCTION__ << std::endl;
                  }

                  int main() {
                  int16_t a = 10;
                  int16_t b = 20;
                  print_type(a);
                  print_type(b);
                  print_type(a - b);
                  return 0;
                  }


                  a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.






                  share|improve this answer













                  The problem isn't with auto here. When you subtract two int16_t values, the result is an int. We can demonstrate it with this code here:



                  #include <iostream>
                  #include <cstdint>
                  using namespace std;

                  template<class T>
                  void print_type(T) {
                  std::cout << __PRETTY_FUNCTION__ << std::endl;
                  }

                  int main() {
                  int16_t a = 10;
                  int16_t b = 20;
                  print_type(a);
                  print_type(b);
                  print_type(a - b);
                  return 0;
                  }


                  a and b are both short ints, but when you add or subtract them it produces a regular int. This is to help prevent overflow / and is also for backwards compatibility.







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Apr 12 at 4:36









                  J. Antonio PerezJ. Antonio Perez

                  2,768922




                  2,768922

























                      4














                      This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.






                      share|improve this answer




























                        4














                        This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.






                        share|improve this answer


























                          4












                          4








                          4







                          This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.






                          share|improve this answer













                          This phenomenon is called the usual arithmetic conversions. It is defined in the C and C++ standards and (roughly said) converts anything smaller than an int to an int. It converts larger types as well. Take some time and read about it, you'll need it quite often.







                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Apr 12 at 5:09









                          Roland IlligRoland Illig

                          31k96493




                          31k96493






























                              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.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55644479%2fc-auto-on-int16-t-casts-to-integer%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

                              Plaza Victoria

                              Puebla de Zaragoza

                              Musa