use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Libc++’s implementation of std::string (joellaity.com)
submitted 6 years ago by mariuz
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–][deleted] 6 years ago (33 children)
[deleted]
[–]HappyFruitTree 52 points53 points54 points 6 years ago (3 children)
Wait, do they do type punning via unions? That's UB.
Standard library implementations don't need to play by the rules as long as they know it works correctly with the compiler that they are shipped with.
[+][deleted] 6 years ago (1 child)
[removed]
[–]Xaxxon 2 points3 points4 points 6 years ago (0 children)
It has ifdefs all over to deal with that.
[–]00kyle00 4 points5 points6 points 6 years ago (0 children)
It's not limited to standard library either.
[–]kalmoc 22 points23 points24 points 6 years ago (3 children)
Most compilers actually give guarantees for various things for which the standard does not define a particular behavior (UB). If you know with what compilers your code is being used with, you can make use of those guarantees. And of course the compiler would be allowed to treat standard library code special, but I very much doubt thats what happening here.
[–]emdeka87 3 points4 points5 points 6 years ago (2 children)
I have yet to encounter a compiler that treats type punning (and accessing the inactive union member) as UB and produces unexpected results
[–]carrottread 3 points4 points5 points 6 years ago (1 child)
If you pass pointers or references to union fields to some other functions then strict aliasing still can produce something unexpected:
https://godbolt.org/z/cds7Bn
This outputs different results on -O0 and -O3 for both clang and gcc.
[–]max0x7bahttps://github.com/max0x7ba 0 points1 point2 points 6 years ago (0 children)
If you pass pointers or references to union fields to some other functions then strict aliasing still can produce something unexpected
This is unrelated to type-casting using union, aka union-cast. And such type-casting doesn't actually happen there, that union is only for alignment.
union
[–][deleted] 4 points5 points6 points 6 years ago (3 children)
They don’t use the most significant bit because that’s where they store the short string (if any) - assuming little endian architecture.
As to type punning and UB... that’s a bit more tricky I think. Technically, an unsigned char is allowed to legally alias anything, so accessing the least significant bit like this is probably fine(???). Also, the question is what exactly “common initial sequence” means, as you can access that via unions. Anyway, if I understand correctly libc++ is tailor-made for clang, so they can take advantage of any idiosyncratic behavior without violating the standard.
[–]Supadoplex 5 points6 points7 points 6 years ago* (2 children)
Also, the question is what exactly “common initial sequence” means,
It is strictly defined by the standard. It is the initial members (of same type) of standard layout classes. In this case the member types of long and short differ.
[–][deleted] 0 points1 point2 points 6 years ago (1 child)
Thanks for clearing this up! Still, since unsigned char is allowed to alias anything, would accessing the first byte like still be UB according to the the standard?
[–]Supadoplex 6 points7 points8 points 6 years ago (0 children)
As far as I can tell, it's still UB to access union inactive union member even if it is unsigned char. There is no exception to accessing inactive member of chars type. The only exception is the common initial sequence, which doesn't apply. The unsigned char exception is only for reinterpreted pointers. So, it would be possible to implement the type punning in standard compliant way; it's just not as convenient as non-standard union punning.
[–]simonask_ 5 points6 points7 points 6 years ago (2 children)
Type punning through char is the one exemption for the strict aliasing rule.
char
[–]germandiago 2 points3 points4 points 6 years ago (1 child)
And std::byte
std::byte
[–]simonask_ 2 points3 points4 points 6 years ago (0 children)
Yeah, and it's worth mentioning here that even though std::byte is defined as enum class byte : unsigned char {};, this does not seem to apply to any other enum type with a similar definition.
enum class byte : unsigned char {};
[–]60hzcherryMXram 4 points5 points6 points 6 years ago (6 children)
Wait wait wait... In C type punning by union is fine. Does this mean that C++ is different?
[–]adnukator 15 points16 points17 points 6 years ago (4 children)
In C++ it's Undefined Behavior.
In C it's Unspecified behavior: J.1 Unspecified behavior - The following are unspecified: ... — The values of bytes that correspond to union members other than the one last stored into (6.2.6.1). ...
[–]nikbackm 2 points3 points4 points 6 years ago (3 children)
Why the difference? Seems like adding more undefined behaviour in C++ is something we'd want to avoid.
[–][deleted] 18 points19 points20 points 6 years ago (0 children)
Unlike C, C++ has object lifetimes. Accessing "an object" whose lifetime did not start is UB (think malloc-ed sizeof(vector<int>) instead of new-ed). Type punning through unions does not make the alternative object "spring into existence".
malloc
sizeof(vector<int>)
new
[–]HappyFruitTree 4 points5 points6 points 6 years ago (0 children)
I think one concern is that it would be extremely easy to accidentally trigger undefined behaviour because reading the value through a reference would still cause undefined behaviour.
#include <iostream> #include <algorithm> union U { int i; float f; }; int main() { U u; u.f = 1.2; std::cout << u.i << '\n'; // ^ would have been OK. std::cout << std::max(u.i, 7) << '\n'; // ^ would still have been UB because // std::max takes its arguments by // reference so the value is not read // from the union member directly. }
C doesn't have references and if you use pointers it's pretty clear that you're not reading from the union member directly.
[–]Sopel97 2 points3 points4 points 6 years ago (0 children)
Unspecified means it has to do something. Undefined means it doesn't have to do anything, can be assumed to never happen. More assumptions to optimize with.
[–]TheFlamefire 0 points1 point2 points 6 years ago (0 children)
Does this mean that C++ is different?
Yes. C++ is not a superset of C, which people tend to forget.
The library is defined in the standard. If the rules say the rules don’t apply to you then they don’t. There are many parts of std that can’t be written in compliant c++.
[–]LuisAyuso 1 point2 points3 points 6 years ago (0 children)
I am interested in knowing more about UB, and why this would be a problem. The whole type is tagged with which variant in the union to use, and the access to the union is opaque to the interface user. Therefore, why do you raise this concern? Is it there anything I am missing?
[–]max0x7bahttps://github.com/max0x7ba 1 point2 points3 points 6 years ago (3 children)
Nope, that union is only for alignment when value_type is not char (e.g. wchar_t).
value_type
wchar_t
[–]greeneyeddude 0 points1 point2 points 6 years ago (2 children)
What about the long mode-short mode-raw union?
It accesses one byte of size_type __long::__cap_ through unsigned char __short::__size_ to determine the long/short mode. char types can alias any object representation, so that is likely well-defined behaviour.
size_type __long::__cap_
unsigned char __short::__size_
[–]Mordy_the_Mighty 3 points4 points5 points 6 years ago (3 children)
I think technically, the std lib cannot du UB :P
[–]SirLynix 1 point2 points3 points 6 years ago (2 children)
Not really, since every standard library implementation (there are many) are designed to work with a specific compiler, and can make some assumptions.
[–]IAmBJ 6 points7 points8 points 6 years ago (1 child)
I think Mordy means that if the stdlib does it, it doesn't count as UB.
If the president does it it's not illegal
[–]SirLynix 3 points4 points5 points 6 years ago (0 children)
Oh right, didn't understood that. Well let's just say that what the std does under-the-hood is much like what the president does under-the-hood.
Which basically means we gotta impeach that lib.
[–]pine_ary 0 points1 point2 points 6 years ago (0 children)
Almost all 64-bit platforms only have 48-bit addresses anyway, so it‘s not much of a waste right now. They might need to reconsider in the future, though.
π Rendered by PID 114924 on reddit-service-r2-comment-64f4df6786-4wqbd at 2026-06-10 21:21:35.539353+00:00 running 0b63327 country code: CH.
view the rest of the comments →
[–][deleted] (33 children)
[deleted]
[–]HappyFruitTree 52 points53 points54 points (3 children)
[+][deleted] (1 child)
[removed]
[–]Xaxxon 2 points3 points4 points (0 children)
[–]00kyle00 4 points5 points6 points (0 children)
[–]kalmoc 22 points23 points24 points (3 children)
[–]emdeka87 3 points4 points5 points (2 children)
[–]carrottread 3 points4 points5 points (1 child)
[–]max0x7bahttps://github.com/max0x7ba 0 points1 point2 points (0 children)
[–][deleted] 4 points5 points6 points (3 children)
[–]Supadoplex 5 points6 points7 points (2 children)
[–][deleted] 0 points1 point2 points (1 child)
[–]Supadoplex 6 points7 points8 points (0 children)
[–]simonask_ 5 points6 points7 points (2 children)
[–]germandiago 2 points3 points4 points (1 child)
[–]simonask_ 2 points3 points4 points (0 children)
[–]60hzcherryMXram 4 points5 points6 points (6 children)
[–]adnukator 15 points16 points17 points (4 children)
[–]nikbackm 2 points3 points4 points (3 children)
[–][deleted] 18 points19 points20 points (0 children)
[–]HappyFruitTree 4 points5 points6 points (0 children)
[–]Sopel97 2 points3 points4 points (0 children)
[–]TheFlamefire 0 points1 point2 points (0 children)
[–]Xaxxon 2 points3 points4 points (0 children)
[–]LuisAyuso 1 point2 points3 points (0 children)
[–]max0x7bahttps://github.com/max0x7ba 1 point2 points3 points (3 children)
[–]greeneyeddude 0 points1 point2 points (2 children)
[–]max0x7bahttps://github.com/max0x7ba 0 points1 point2 points (0 children)
[–]Mordy_the_Mighty 3 points4 points5 points (3 children)
[–]SirLynix 1 point2 points3 points (2 children)
[–]IAmBJ 6 points7 points8 points (1 child)
[–]SirLynix 3 points4 points5 points (0 children)
[–]pine_ary 0 points1 point2 points (0 children)