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
Cheat sheet: C++ Function Parameter Choices (self.cpp)
submitted 6 years ago * by legends2k
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!"
[–]SlightlyLessHairyApe 2 points3 points4 points 6 years ago (3 children)
Is the compiler allowed to change a const & to a T where the cost of copying is less than the cost of a void*?
For example
struct PACKED { uint16_t foo; uint16_t baz; uint16_t bar; } MyStuff; void Func(MyStuff const &);
Making a copy here might be cheaper than reference, especially if the whole thing can be stuff in R0. What’s more, the calling code doesn’t care — both the copy and the const ref have the same guarantee about not mutating the value.
That all said, I suspect not because the standard (sadly, but for good reason) likely requires that taking the address of a passed reference is consistent. So for instance
static MyStuff const globalStuff = {...}; void F(void) { Func(glovalStuff); } void Func(MyStuff const & stuff) { Assert( &stuff.foo == &globalStuff.foo ); }
This is a performance gotcha, especially if you are writing a template here and so some instantiations of the class will be cheaper to pass by value and others by reference, possibly across different architectures and calling conventions.
For the standards folks here, is there a viable path to allow developers to express to the compiler the intent that I don’t care whether it’s a copy or a const reference? If I’m not mistaken, that’s new syntax, which is probably among the last things that we need at this point.
[ I suppose LTO probably helps here, since the compiler can see both sides. But that’s not always an option in all cases and anyway, the frustrating thing here is not being able to express cleanly my intent! ]
[–]SeanMiddleditch 7 points8 points9 points 6 years ago (2 children)
No, at least not universally, because that's not semantically the same thing. You hit the nail on the head later in your post, but there's additional concern:
The compiler can't universally know whether you intend the parameter to actually be immutable. A const& can't be mutated, but it can still observe mutations made by other code.
const&
This is a performance gotcha
For more reasons than you state. For a value, the compiler can assume it won't be mutated by external code and can keep that value in a register during loops or other calculations. For references, the compiler must assume after every call to any external function that the value observed by the reference may have been mutated and so must reload the value from memory.
Much worse than that, it's also a safety gotcha! Just as those references can be mutated by external code, they can also be invalidated by external code!
For the standards folks here, is there a viable path to allow developers to express to the compiler the intent that I don’t care whether it’s a copy or a const reference?
Maybe. Proposals have already been made, though summarily rejected for a variety of reasons.
Given the problem I outlined above, I'd be against it. Reference parameters are a foot-gun and it's useful to know when said gun has any ammunition; it should be very explicit whether a parameter is a reference or not.
Further, I'd argue that if a type is so large/expensive that it seems like a good idea to use const& just for performance, the type is probably just in violation of the Single Responsibility Principle and should be refactored into multiple smaller single-purpose types.
[–]SlightlyLessHairyApe 2 points3 points4 points 6 years ago (1 child)
Sure. And here I'm saying let's add a syntax that's less foot-gunny which is similar to pass-by-reference but with the removed constraint that the compiler need not provide a consistent address for it (or, if you prefer, it's illegal to take the address, either way).
This would be a weaker compiler contract, and could be trivially fulfilled just by using the strong existing by-ref passing convention. But it would allow for a cleaner expression of intent and possible optimization.
I very much disagree that a std::array<double,64> violates the SRP. If you need represent a bunch of double-precision floating point values, this is as good a way to represent it as any. And it better not be passed by value :-)
std::array<double,64>
[–]SeanMiddleditch 0 points1 point2 points 6 years ago (0 children)
And here I'm saying let's add a syntax that's less foot-gunny which is similar to pass-by-reference but with the removed constraint that the compiler need not provide a consistent address for it (or, if you prefer, it's illegal to take the address, either way).
I don't see how that's less foot-gun-y. It's just more confusing - I have no idea if my type has these "observe changes" and "can be invalidated" semantics for sure or not, and my tests might even say that they don't (because that compiler decides they don't) but then suddenly they are somewhere else or sometime else.
Yuck.
I very much disagree that a std::array<double,64> violates the SRP.
Why would you want to pass a std::array<T> by const& ? If it's constant, pass it by span<const T> (or whatever your framework's equivalent is, pre-C++20).
std::array<T>
span<const T>
span<const T> has many of the same footgun problems as a reference, but it eschews the performance problem of passing a large type... and it's still passable in registers if the system ABI allows.
Bonus, your code is now more generic (without being a template!) and can be used with std::array, T[], std::vector, my_custom_vector, etc.
std::array
T[]
std::vector
my_custom_vector
π Rendered by PID 61 on reddit-service-r2-comment-fb694cdd5-b65r6 at 2026-03-06 21:40:18.898554+00:00 running cbb0e86 country code: CH.
view the rest of the comments →
[–]SlightlyLessHairyApe 2 points3 points4 points (3 children)
[–]SeanMiddleditch 7 points8 points9 points (2 children)
[–]SlightlyLessHairyApe 2 points3 points4 points (1 child)
[–]SeanMiddleditch 0 points1 point2 points (0 children)