Signedness aliasing using reinterpret_castWhat is the strict aliasing rule?What is the strict aliasing rule?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?When to use reinterpret_cast?Generic char[] based storage and avoiding strict-aliasing related UBDo the c++11 strict alias rules allow accessing uint64_t via char *, char(&)[N],even std::array<char, N>& with -fstrict-aliasing -Wstrict-aliasing=2?Is it a strict aliasing violation to alias a struct as its first member?std::launder and strict aliasing rulereinterpret_cast vs strict aliasingStrict Aliasing Rule and Type Aliasing in C++Dealing with undefined behavior when using reinterpret_cast in a memory mapping

Teacher help me explain this to my students

Did people Unsnap to where they were?

Count Even Digits In Number

Externally monitoring CPU/SSD activity without software access

Why is a `for` loop so much faster to count True values?

Plot twist where the antagonist wins

Purpose and meaning of "dabei" in the sentence "sehen Sie dabei nicht ins Bildlexikon"?

Where have Brexit voters gone?

what kind of chord progession is this?

Count rotary dial pulses in a phone number (including letters)

Can I tell a prospective employee that everyone in the team is leaving?

How to Pin Point Large File eating space in Fedora 18

How to know if a folder is a symbolic link?

Is "cool" appropriate or offensive to use in IMs?

The usage of "run a mile" in a sentence

Is it rude to call a professor by their last name with no prefix in a non-academic setting?

I know that there is a preselected candidate for a position to be filled at my department. What should I do?

What is the object moving across the ceiling in this stock footage?

Where can I find visible/radio telescopic observations of the center of the Milky Way galaxy?

Why were helmets and other body armour not commonplace in the 1800s?

Why didn't Thanos use the Time Stone to stop the Avengers' plan?

Compaq Portable vs IBM 5155 Portable PC

Gladys goes shopping

Have 1.5% of all nuclear reactors ever built melted down?



Signedness aliasing using reinterpret_cast


What is the strict aliasing rule?What is the strict aliasing rule?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?When to use reinterpret_cast?Generic char[] based storage and avoiding strict-aliasing related UBDo the c++11 strict alias rules allow accessing uint64_t via char *, char(&)[N],even std::array<char, N>& with -fstrict-aliasing -Wstrict-aliasing=2?Is it a strict aliasing violation to alias a struct as its first member?std::launder and strict aliasing rulereinterpret_cast vs strict aliasingStrict Aliasing Rule and Type Aliasing in C++Dealing with undefined behavior when using reinterpret_cast in a memory mapping






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








10















Take the following code



#include <iostream>

void func()
int i = 2147483640;
while (i < i + 1)

std::cerr << i << 'n';
++i;


return;


int main()
func();



This code is clearly wrong, as the while loop can only terminate if the signed int i overflowed, which is UB, and hence the compiler may for instance optimize this into an infinite loop (which Clang does on -O3), or do other sorts of funky things. My question now is: from my reading of the C++ standard, types that are equivalent up to signedness may alias (i.e. pointers int* and unsigned* may alias). In order to do some funky signed "wrapping", does the following have undefined behavior or not?



#include <iostream>

static int safe_inc(int a)

++reinterpret_cast<unsigned&>(a);
return a;


void func()
int i = 2147483640;
while (i < safe_inc(i))

std::cerr << i << 'n';
++i;


return;


int main()
func();



I have tried the above code with both Clang 8 and GCC 9 on -O3 with -Wall -Wextra -Wpedantic -O3 -fsanitize=address,undefined arguments and get no errors or warnings and the loop terminates after wrapping to INT_MIN.



cppreference.com tells me that




Type aliasing



Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:



  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.



which from my reading means that for purposes of type aliasing, signedness is not considered, and the code using reinterpret_cast has well-defined semantics (albeit being somewhat cheesy anyhow).










share|improve this question









New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

    – xryl669
    8 hours ago






  • 3





    @LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

    – Nicol Bolas
    8 hours ago







  • 2





    @SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

    – Nicol Bolas
    7 hours ago







  • 2





    Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

    – Lightness Races in Orbit
    7 hours ago






  • 2





    @SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

    – Nicol Bolas
    7 hours ago

















10















Take the following code



#include <iostream>

void func()
int i = 2147483640;
while (i < i + 1)

std::cerr << i << 'n';
++i;


return;


int main()
func();



This code is clearly wrong, as the while loop can only terminate if the signed int i overflowed, which is UB, and hence the compiler may for instance optimize this into an infinite loop (which Clang does on -O3), or do other sorts of funky things. My question now is: from my reading of the C++ standard, types that are equivalent up to signedness may alias (i.e. pointers int* and unsigned* may alias). In order to do some funky signed "wrapping", does the following have undefined behavior or not?



#include <iostream>

static int safe_inc(int a)

++reinterpret_cast<unsigned&>(a);
return a;


void func()
int i = 2147483640;
while (i < safe_inc(i))

std::cerr << i << 'n';
++i;


return;


int main()
func();



I have tried the above code with both Clang 8 and GCC 9 on -O3 with -Wall -Wextra -Wpedantic -O3 -fsanitize=address,undefined arguments and get no errors or warnings and the loop terminates after wrapping to INT_MIN.



cppreference.com tells me that




Type aliasing



Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:



  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.



which from my reading means that for purposes of type aliasing, signedness is not considered, and the code using reinterpret_cast has well-defined semantics (albeit being somewhat cheesy anyhow).










share|improve this question









New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.



















  • Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

    – xryl669
    8 hours ago






  • 3





    @LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

    – Nicol Bolas
    8 hours ago







  • 2





    @SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

    – Nicol Bolas
    7 hours ago







  • 2





    Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

    – Lightness Races in Orbit
    7 hours ago






  • 2





    @SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

    – Nicol Bolas
    7 hours ago













10












10








10


1






Take the following code



#include <iostream>

void func()
int i = 2147483640;
while (i < i + 1)

std::cerr << i << 'n';
++i;


return;


int main()
func();



This code is clearly wrong, as the while loop can only terminate if the signed int i overflowed, which is UB, and hence the compiler may for instance optimize this into an infinite loop (which Clang does on -O3), or do other sorts of funky things. My question now is: from my reading of the C++ standard, types that are equivalent up to signedness may alias (i.e. pointers int* and unsigned* may alias). In order to do some funky signed "wrapping", does the following have undefined behavior or not?



#include <iostream>

static int safe_inc(int a)

++reinterpret_cast<unsigned&>(a);
return a;


void func()
int i = 2147483640;
while (i < safe_inc(i))

std::cerr << i << 'n';
++i;


return;


int main()
func();



I have tried the above code with both Clang 8 and GCC 9 on -O3 with -Wall -Wextra -Wpedantic -O3 -fsanitize=address,undefined arguments and get no errors or warnings and the loop terminates after wrapping to INT_MIN.



cppreference.com tells me that




Type aliasing



Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:



  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.



which from my reading means that for purposes of type aliasing, signedness is not considered, and the code using reinterpret_cast has well-defined semantics (albeit being somewhat cheesy anyhow).










share|improve this question









New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.











Take the following code



#include <iostream>

void func()
int i = 2147483640;
while (i < i + 1)

std::cerr << i << 'n';
++i;


return;


int main()
func();



This code is clearly wrong, as the while loop can only terminate if the signed int i overflowed, which is UB, and hence the compiler may for instance optimize this into an infinite loop (which Clang does on -O3), or do other sorts of funky things. My question now is: from my reading of the C++ standard, types that are equivalent up to signedness may alias (i.e. pointers int* and unsigned* may alias). In order to do some funky signed "wrapping", does the following have undefined behavior or not?



#include <iostream>

static int safe_inc(int a)

++reinterpret_cast<unsigned&>(a);
return a;


void func()
int i = 2147483640;
while (i < safe_inc(i))

std::cerr << i << 'n';
++i;


return;


int main()
func();



I have tried the above code with both Clang 8 and GCC 9 on -O3 with -Wall -Wextra -Wpedantic -O3 -fsanitize=address,undefined arguments and get no errors or warnings and the loop terminates after wrapping to INT_MIN.



cppreference.com tells me that




Type aliasing



Whenever an attempt is made to read or modify the stored value of an object of type DynamicType through a glvalue of type AliasedType, the behavior is undefined unless one of the following is true:



  • AliasedType is the (possibly cv-qualified) signed or unsigned variant of DynamicType.



which from my reading means that for purposes of type aliasing, signedness is not considered, and the code using reinterpret_cast has well-defined semantics (albeit being somewhat cheesy anyhow).







c++ language-lawyer undefined-behavior signed reinterpret-cast






share|improve this question









New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.










share|improve this question









New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








share|improve this question




share|improve this question








edited 7 hours ago







Jonas Müller













New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.








asked 8 hours ago









Jonas MüllerJonas Müller

513




513




New contributor



Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.




New contributor




Jonas Müller is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.














  • Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

    – xryl669
    8 hours ago






  • 3





    @LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

    – Nicol Bolas
    8 hours ago







  • 2





    @SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

    – Nicol Bolas
    7 hours ago







  • 2





    Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

    – Lightness Races in Orbit
    7 hours ago






  • 2





    @SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

    – Nicol Bolas
    7 hours ago

















  • Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

    – xryl669
    8 hours ago






  • 3





    @LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

    – Nicol Bolas
    8 hours ago







  • 2





    @SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

    – Nicol Bolas
    7 hours ago







  • 2





    Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

    – Lightness Races in Orbit
    7 hours ago






  • 2





    @SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

    – Nicol Bolas
    7 hours ago
















Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

– xryl669
8 hours ago





Since you reinterpret the signed int as an unsigned value, the code is as correct as if you used unsigned value from the beginning (and casting the cerr output to signed).

– xryl669
8 hours ago




3




3





@LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

– Nicol Bolas
8 hours ago






@LightnessRacesinOrbit: [basic.lval]/11 lays down the validity of this access. What is missing is what the behavior is of modifying an unsigned/signed object through a reference to its signed/unsigned version of it. But I don't see a statement forbidding it.

– Nicol Bolas
8 hours ago





2




2





@SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

– Nicol Bolas
7 hours ago






@SergeyA: Then point to the line in the specification that says what actually happens when you write to a signed object via a reference to an unsigned one. Because I can point to lines in the specification that says what happens when you, for example, call a member function of a derived class through a base class pointer/reference. But no such similar statements exist for signed/unsigned. The conversion is legit; the access is legit, but what happens is simply not stated by the spec.

– Nicol Bolas
7 hours ago





2




2





Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

– Lightness Races in Orbit
7 hours ago





Indeed. This kind of thing has always been underspecified for my liking. It's one of the few areas of the standard that seems to assume close-to-the-metal bit logic in places

– Lightness Races in Orbit
7 hours ago




2




2





@SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

– Nicol Bolas
7 hours ago





@SergeyA: "Could it be underspecified?" Yes, this is a defect in the spec. And with the two's complement change in C++20, it can be resolved in a completely well-defined way. There just has to be wording somewhere to do it.

– Nicol Bolas
7 hours ago












2 Answers
2






active

oldest

votes


















6














Aliasing here is perfectly legal. See http://eel.is/c++draft/expr.prop#basic.lval-11.2:




If a program attempts to access the stored value of an object through
a glvalue whose type is not similar ([conv.qual]) to one of the
following types the behavior is undefined:53



(11.1) the dynamic type of the object,



(11.2) a type that is the signed or unsigned type
corresponding to the dynamic type of the object




I think, it is also worth talking about the actual overflow question, which does not necessarily require reinterpret_cast. The very same effect could be achieved with implicit integral conversions



 unsigned x = i;
++x;
i = x; // this would serve you just fine.


This code would be implementation defined pre-C++20, since you would be converting from the value which can't be represented by destination type.



Since C++20 this code will be well-formed.



See https://en.cppreference.com/w/cpp/language/implicit_conversion



On a side note, you might as well start with unsigned type if you want integer overflow semantic.






share|improve this answer

























  • i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

    – formerlyknownas_463035818
    8 hours ago






  • 3





    This doesn't answer the question about aliasing though does it

    – Lightness Races in Orbit
    8 hours ago






  • 1





    @JonasMüller is your question about incrementing or aliasing?

    – SergeyA
    8 hours ago






  • 1





    @formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

    – NathanOliver
    8 hours ago







  • 1





    I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

    – Jonas Müller
    8 hours ago


















5














Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11




If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:



  • the dynamic type of the object,


  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]







share|improve this answer

























  • Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

    – Lightness Races in Orbit
    8 hours ago







  • 2





    @LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

    – Oliv
    8 hours ago












  • Okay, thanks, that's concrete. :)

    – Lightness Races in Orbit
    7 hours ago











  • For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

    – Oliv
    7 hours ago











  • Well it's not my code :)

    – Lightness Races in Orbit
    7 hours ago











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
);



);






Jonas Müller is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56295309%2fsignedness-aliasing-using-reinterpret-cast%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









6














Aliasing here is perfectly legal. See http://eel.is/c++draft/expr.prop#basic.lval-11.2:




If a program attempts to access the stored value of an object through
a glvalue whose type is not similar ([conv.qual]) to one of the
following types the behavior is undefined:53



(11.1) the dynamic type of the object,



(11.2) a type that is the signed or unsigned type
corresponding to the dynamic type of the object




I think, it is also worth talking about the actual overflow question, which does not necessarily require reinterpret_cast. The very same effect could be achieved with implicit integral conversions



 unsigned x = i;
++x;
i = x; // this would serve you just fine.


This code would be implementation defined pre-C++20, since you would be converting from the value which can't be represented by destination type.



Since C++20 this code will be well-formed.



See https://en.cppreference.com/w/cpp/language/implicit_conversion



On a side note, you might as well start with unsigned type if you want integer overflow semantic.






share|improve this answer

























  • i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

    – formerlyknownas_463035818
    8 hours ago






  • 3





    This doesn't answer the question about aliasing though does it

    – Lightness Races in Orbit
    8 hours ago






  • 1





    @JonasMüller is your question about incrementing or aliasing?

    – SergeyA
    8 hours ago






  • 1





    @formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

    – NathanOliver
    8 hours ago







  • 1





    I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

    – Jonas Müller
    8 hours ago















6














Aliasing here is perfectly legal. See http://eel.is/c++draft/expr.prop#basic.lval-11.2:




If a program attempts to access the stored value of an object through
a glvalue whose type is not similar ([conv.qual]) to one of the
following types the behavior is undefined:53



(11.1) the dynamic type of the object,



(11.2) a type that is the signed or unsigned type
corresponding to the dynamic type of the object




I think, it is also worth talking about the actual overflow question, which does not necessarily require reinterpret_cast. The very same effect could be achieved with implicit integral conversions



 unsigned x = i;
++x;
i = x; // this would serve you just fine.


This code would be implementation defined pre-C++20, since you would be converting from the value which can't be represented by destination type.



Since C++20 this code will be well-formed.



See https://en.cppreference.com/w/cpp/language/implicit_conversion



On a side note, you might as well start with unsigned type if you want integer overflow semantic.






share|improve this answer

























  • i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

    – formerlyknownas_463035818
    8 hours ago






  • 3





    This doesn't answer the question about aliasing though does it

    – Lightness Races in Orbit
    8 hours ago






  • 1





    @JonasMüller is your question about incrementing or aliasing?

    – SergeyA
    8 hours ago






  • 1





    @formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

    – NathanOliver
    8 hours ago







  • 1





    I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

    – Jonas Müller
    8 hours ago













6












6








6







Aliasing here is perfectly legal. See http://eel.is/c++draft/expr.prop#basic.lval-11.2:




If a program attempts to access the stored value of an object through
a glvalue whose type is not similar ([conv.qual]) to one of the
following types the behavior is undefined:53



(11.1) the dynamic type of the object,



(11.2) a type that is the signed or unsigned type
corresponding to the dynamic type of the object




I think, it is also worth talking about the actual overflow question, which does not necessarily require reinterpret_cast. The very same effect could be achieved with implicit integral conversions



 unsigned x = i;
++x;
i = x; // this would serve you just fine.


This code would be implementation defined pre-C++20, since you would be converting from the value which can't be represented by destination type.



Since C++20 this code will be well-formed.



See https://en.cppreference.com/w/cpp/language/implicit_conversion



On a side note, you might as well start with unsigned type if you want integer overflow semantic.






share|improve this answer















Aliasing here is perfectly legal. See http://eel.is/c++draft/expr.prop#basic.lval-11.2:




If a program attempts to access the stored value of an object through
a glvalue whose type is not similar ([conv.qual]) to one of the
following types the behavior is undefined:53



(11.1) the dynamic type of the object,



(11.2) a type that is the signed or unsigned type
corresponding to the dynamic type of the object




I think, it is also worth talking about the actual overflow question, which does not necessarily require reinterpret_cast. The very same effect could be achieved with implicit integral conversions



 unsigned x = i;
++x;
i = x; // this would serve you just fine.


This code would be implementation defined pre-C++20, since you would be converting from the value which can't be represented by destination type.



Since C++20 this code will be well-formed.



See https://en.cppreference.com/w/cpp/language/implicit_conversion



On a side note, you might as well start with unsigned type if you want integer overflow semantic.







share|improve this answer














share|improve this answer



share|improve this answer








edited 8 hours ago

























answered 8 hours ago









SergeyASergeyA

46k54193




46k54193












  • i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

    – formerlyknownas_463035818
    8 hours ago






  • 3





    This doesn't answer the question about aliasing though does it

    – Lightness Races in Orbit
    8 hours ago






  • 1





    @JonasMüller is your question about incrementing or aliasing?

    – SergeyA
    8 hours ago






  • 1





    @formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

    – NathanOliver
    8 hours ago







  • 1





    I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

    – Jonas Müller
    8 hours ago

















  • i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

    – formerlyknownas_463035818
    8 hours ago






  • 3





    This doesn't answer the question about aliasing though does it

    – Lightness Races in Orbit
    8 hours ago






  • 1





    @JonasMüller is your question about incrementing or aliasing?

    – SergeyA
    8 hours ago






  • 1





    @formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

    – NathanOliver
    8 hours ago







  • 1





    I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

    – Jonas Müller
    8 hours ago
















i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

– formerlyknownas_463035818
8 hours ago





i wonder if one cannot do the same without the reinterpret_cast via unsigned x = a; ++x; return x;. Would that not have the same effect, but valid already pre c++20?

– formerlyknownas_463035818
8 hours ago




3




3





This doesn't answer the question about aliasing though does it

– Lightness Races in Orbit
8 hours ago





This doesn't answer the question about aliasing though does it

– Lightness Races in Orbit
8 hours ago




1




1





@JonasMüller is your question about incrementing or aliasing?

– SergeyA
8 hours ago





@JonasMüller is your question about incrementing or aliasing?

– SergeyA
8 hours ago




1




1





@formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

– NathanOliver
8 hours ago






@formerlyknownas_463035818 if a is INT_MAX then x would not fit back into a making it implementation defined behavior.

– NathanOliver
8 hours ago





1




1





I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

– Jonas Müller
8 hours ago





I agree, there's a second implicit question in here (which concerns the overflow part), but the primary question is whether the use of reinterpret_cast is valid here.

– Jonas Müller
8 hours ago













5














Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11




If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:



  • the dynamic type of the object,


  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]







share|improve this answer

























  • Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

    – Lightness Races in Orbit
    8 hours ago







  • 2





    @LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

    – Oliv
    8 hours ago












  • Okay, thanks, that's concrete. :)

    – Lightness Races in Orbit
    7 hours ago











  • For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

    – Oliv
    7 hours ago











  • Well it's not my code :)

    – Lightness Races in Orbit
    7 hours ago















5














Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11




If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:



  • the dynamic type of the object,


  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]







share|improve this answer

























  • Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

    – Lightness Races in Orbit
    8 hours ago







  • 2





    @LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

    – Oliv
    8 hours ago












  • Okay, thanks, that's concrete. :)

    – Lightness Races in Orbit
    7 hours ago











  • For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

    – Oliv
    7 hours ago











  • Well it's not my code :)

    – Lightness Races in Orbit
    7 hours ago













5












5








5







Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11




If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:



  • the dynamic type of the object,


  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]







share|improve this answer















Your code is perfectly legal, cpp reference is a very good source. You can find the same information in the standard [basic.lval]/11




If a program attempts to access the stored value of an object through a glvalue whose type is not similar ([conv.qual]) to one of the following types the behavior is undefined:



  • the dynamic type of the object,


  • a type that is the signed or unsigned type corresponding to the dynamic type of the object,[...]








share|improve this answer














share|improve this answer



share|improve this answer








edited 7 hours ago









Lightness Races in Orbit

300k56486835




300k56486835










answered 8 hours ago









OlivOliv

10.5k12058




10.5k12058












  • Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

    – Lightness Races in Orbit
    8 hours ago







  • 2





    @LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

    – Oliv
    8 hours ago












  • Okay, thanks, that's concrete. :)

    – Lightness Races in Orbit
    7 hours ago











  • For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

    – Oliv
    7 hours ago











  • Well it's not my code :)

    – Lightness Races in Orbit
    7 hours ago

















  • Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

    – Lightness Races in Orbit
    8 hours ago







  • 2





    @LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

    – Oliv
    8 hours ago












  • Okay, thanks, that's concrete. :)

    – Lightness Races in Orbit
    7 hours ago











  • For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

    – Oliv
    7 hours ago











  • Well it's not my code :)

    – Lightness Races in Orbit
    7 hours ago
















Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

– Lightness Races in Orbit
8 hours ago






Hmm what does "corresponding to" mean here? Certainly this is not the same wording Cubbi chose on cppreference ("variant of")

– Lightness Races in Orbit
8 hours ago





2




2





@LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

– Oliv
8 hours ago






@LightnessRacesinOrbit eel.is/c++draft/basic.fundamental#2. Cpp reference prefers plain English, the aim is certainly to be easier to read than the standard.

– Oliv
8 hours ago














Okay, thanks, that's concrete. :)

– Lightness Races in Orbit
7 hours ago





Okay, thanks, that's concrete. :)

– Lightness Races in Orbit
7 hours ago













For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

– Oliv
7 hours ago





For completeness, your code behavior is more specified according to the c++20 standard: eel.is/c++draft/basic.types#basic.fundamental-3. Nevertheless this added paragraph is just a recognition of a fact and you can safely assume your code is portable.

– Oliv
7 hours ago













Well it's not my code :)

– Lightness Races in Orbit
7 hours ago





Well it's not my code :)

– Lightness Races in Orbit
7 hours ago










Jonas Müller is a new contributor. Be nice, and check out our Code of Conduct.









draft saved

draft discarded


















Jonas Müller is a new contributor. Be nice, and check out our Code of Conduct.












Jonas Müller is a new contributor. Be nice, and check out our Code of Conduct.











Jonas Müller is a new contributor. Be nice, and check out our Code of Conduct.














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%2f56295309%2fsignedness-aliasing-using-reinterpret-cast%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

Canceling a color specificationRandomly assigning color to Graphics3D objects?Default color for Filling in Mathematica 9Coloring specific elements of sets with a prime modified order in an array plotHow to pick a color differing significantly from the colors already in a given color list?Detection of the text colorColor numbers based on their valueCan color schemes for use with ColorData include opacity specification?My dynamic color schemes

Invision Community Contents History See also References External links Navigation menuProprietaryinvisioncommunity.comIPS Community ForumsIPS Community Forumsthis blog entry"License Changes, IP.Board 3.4, and the Future""Interview -- Matt Mecham of Ibforums""CEO Invision Power Board, Matt Mecham Is a Liar, Thief!"IPB License Explanation 1.3, 1.3.1, 2.0, and 2.1ArchivedSecurity Fixes, Updates And Enhancements For IPB 1.3.1Archived"New Demo Accounts - Invision Power Services"the original"New Default Skin"the original"Invision Power Board 3.0.0 and Applications Released"the original"Archived copy"the original"Perpetual licenses being done away with""Release Notes - Invision Power Services""Introducing: IPS Community Suite 4!"Invision Community Release Notes

François Viète Contents Biography Work and thought Bibliography See also Notes Further reading External links Navigation menup. 21Google Bookspp. 75–77Google BooksDe thou (from University of Saint Andrews)ArchivedGoogle BooksGoogle BooksGoogle BooksGoogle booksGoogle Bookscc-parthenay.frL'histoire universelle (fr)Universal History (en)ArchivedAdsabs.harvard.eduPagesperso-orange.frArchive.orgChikara Sasaki. Descartes' mathematical thought p.259Google BooksGoogle BooksGoogle Bookspp. 152 and onwardGoogle BooksGoogle BooksScribd.comGoogle Books1257-7979Google BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGoogle BooksGallica.bnf.frGoogle BooksGoogle Books"François Viète"Francois Viète: Father of Modern Algebraic NotationThe Lawyer and the GamblerAbout TarporleySite de Jean-Paul GuichardL'algèbre nouvelle"About the Harmonicon"cb120511976(data)1188044800000 0001 0913 5903n82164680ola2013766880073431702w6vt1sb70287374827140948071409480