Talk:Main Page/suggestions
This page collects edit suggestions from new and logged-out users when editing is temporarily disabled due to vandalism. Click the "+" at the top to leave a message. Please make sure to include a link to the page you are referencing. See /archive and /archive 1 for old suggestions that have been responded to.
[edit] new expression missing exception specs
Somewhere way down in that wall of text there is a mention of std::bad_array_new_length, but that's it. I think there should be a dedicated section "Exceptions" (as in other docs on this site) documenting std::bad_alloc and std::bad_array_new_length as well as the non-throwing versions, as this is pretty fundamental. Perhaps also an example.
Thanks! 213.68.42.195 03:02, 25 February 2019 (PST)
[edit] New user
Hello, I would like to make changes to the C++ compiler support page related to the addition of the "Modules" and "Coroutines" features to C++20. Can somebody give me permissions to edit or otherwise do the changes as per the following articles:
https://www.phoronix.com/scan.php?page=news_item&px=Coroutines-Modules-CPP20 https://herbsutter.com/2019/02/23/trip-report-winter-iso-c-standards-meeting-kona/
--Trifud (talk) 23:15, 26 February 2019 (PST)
- How long time does it take for a user to be activated? --Trifud (talk) 23:09, 28 February 2019 (PST)
[edit] RFC: another implementation of Gadget-StandardRevision
source code |
---|
(function() { 'use strict'; var styles = document.createElement('style'); styles.textContent = '[hidden] { display: none !important; }'; styles.textContent += '.stdrev-rev-hide > tbody > tr > td { border: none !important; padding: 0 !important; }' styles.textContent += '.stdrev-rev-hide > tbody > tr > td:nth-child(2) { display: none; }' styles.textContent += '.stdrev-rev-hide { border: none; }' styles.textContent += '.stdrev-rev-hide > span > .t-mark-rev { display: none; }' document.head.append(styles); var rev = mw.config.get('wgTitle').indexOf('c/') === 0 ? [ 'C89', 'C99', 'C11' ] : [ 'C++98', 'C++03', 'C++11', 'C++14', 'C++17', 'C++20' ]; var select = $('<div class="vectorMenu"></div>').appendTo('#cpp-head-tools-right'); select.append('<h5><span>Std rev</span></h5>'); var list = $('<ul>').appendTo($('<div class="menu">').appendTo(select)); $.each(['DIFF'].concat(rev), function(i, v) { list.append('<li><a href="#'+v+'">'+v+'</a></li>'); }); list.on('click', 'a', function(e) { list.find('a').css('font-weight', 'normal'); $(this).css('font-weight', 'bold'); curr_rev = e.target.innerText; on_rev_changed(); }); var curr_rev = 'DIFF'; // Returns true if an element should be shown in the current revision, that is, either curr_rev is // DIFF (i.e. show all), or curr_rev is within the range [since, until). The range [since, until) // is inspected from the classes of `el`. // `el` may be the same element as the one to be shown if it has the needed classes, or it may be a // revision marker or a collection thereof (e.g. one expanded from {{mark since foo}}, or from the // {{mark since foo}}{{mark until bar}} combo). // `el` may be either a HTML element or a jQuery object. // Note that this correctly handle the case when `el` represents an empty set of elements (in which // case the element is always shown). function should_be_shown(el) { if (curr_rev === 'DIFF') return true; var curr_revid = rev.indexOf(curr_rev); var since = 0, until = rev.length; $.each(rev, function(i) { var ssince = 't-since-'+rev[i].toLowerCase().replace(/\+/g, 'x'); var suntil = 't-until-'+rev[i].toLowerCase().replace(/\+/g, 'x'); if ($(el).hasClass(ssince)) since = i; if ($(el).hasClass(suntil)) until = i; }); return since <= curr_revid && curr_revid < until; } // Called when user changes the selected revision. Inside this function, curr_rev is already set to // the value after the change. function on_rev_changed() { handle_dcl(); renumber_dcl(); handle_dsc(); handle_nv(); handle_rev(); handle_headings(); handle_list_items(); $('.t-rev-begin, .t-rev-inl').toggleClass('stdrev-rev-hide', curr_rev !== 'DIFF'); $('.t-mark-rev').each(function() { this.hidden = curr_rev !== 'DIFF'; if ($(this.nextSibling).is('br')) this.nextSibling.hidden = curr_rev !== 'DIFF'; }); } // Returns true if the jQuery object `el` contains at least one element, and all contained elements // are hidden; otherwise returns false. // This is used to hide a 'parent' or 'heading' element when all its contents are hidden. function all_hidden(el) { return $(el).length > 0 && !$(el).is(':not([hidden])'); } // Hide or show the elements expanded from the {{dcl ...}} template family. See documentation at // https://en.cppreference.com/w/Template:dcl/doc . // The dcl items (expanded from {{dcl | ... }}) may either appear alone or as children of versioned // declaration list (expanded from {{dcl rev begin | ... }}). In the latter case, the revision may // be supplied by the dcl items or by the dcl-rev (in the latter case the dcl-rev has class // t-dcl-rev-notes). // For the use of renumber_dcl(), each dcl-rev is marked as hidden if all its children dcl items // are hidden, and vice versa. function handle_dcl() { $('.t-dcl').each(function() { this.hidden = !should_be_shown(this); }); $('.t-dcl-rev').each(function() { if ($(this).is('.t-dcl-rev-notes')) { var hidden = !should_be_shown(this); this.hidden = hidden; $(this).find('.t-dcl').each(function() { this.hidden = hidden; }); } else { this.hidden = all_hidden($(this).find('.t-dcl')); } }); $('.t-dcl-begin .t-dsc-header').each(function() { var marker = $(this).find('> td > div > .t-mark-rev'); var lastheader = $(this).nextUntil(':not(.t-dsc-header)').addBack(); var elts = lastheader.nextUntil('.t-dsc-header').filter('.t-dcl, .t-dcl-rev'); this.hidden = all_hidden(elts) || !should_be_shown(marker); }); $('.t-dcl-h').each(function() { this.hidden = all_hidden($(this).nextUntil(':not(.t-dcl, .t-dcl-rev)')); }); } // Ensure that each visible dcl item in a dcl list is contiguously numbered, and rewrite mentions // to these numbers to use the modified numbering. // If a list item (e.g. those expanded from @m@) contains no number after the rewrite (i.e. it's // inapplicable in current revision), it is hidden. // Note that the use of '~ * .t-li, ~ * .t-v' effectively establishes a kind of scoping: only // numbers that appear after the dcl list and are more nested in the DOM hierarchy are affected // by the renumbering. // Requires that handle_dcl() has been called. function renumber_dcl() { $('.t-dcl-begin').each(function() { var numbering_map = []; var i = 0; $(this).find('.t-dcl, .t-dcl-rev').each(function() { var num_cell; if ($(this).is('.t-dcl')) num_cell = $(this).children('td:nth-child(2)'); else num_cell = $(this).find('> tr.t-dcl-rev-aux > td:nth-child(2)'); var number_text = /\s*\((\d+)\)\s*/.exec(num_cell.text()); if (!num_cell.attr('data-orig-num') && number_text) num_cell.attr('data-orig-num', number_text[1]); var original_num = num_cell.attr('data-orig-num'); if (original_num) { if (! numbering_map[original_num]) numbering_map[original_num] = $(this).is('[hidden]') ? null : ++i; num_cell.text('('+numbering_map[original_num]+')'); } }); $(this).find('~ * .t-li, ~ * .t-v').each(function() { if (! $(this).attr('data-orig-v')) $(this).attr('data-orig-v', $(this).text().replace(/[()]/g, '')); var original_numbers = []; $.each($(this).attr('data-orig-v').split(','), function(i, v) { var match = /(\d+)(?:-(\d+))?/.exec(v); if (match[2]) for (var i = +match[1]; +i <= +match[2]; ++i) original_numbers.push(i); else original_numbers.push(match[1]); }); var numbers = $.map(original_numbers, function(x) { return numbering_map[x]; }); var s = []; for (var i = 0; i < numbers.length; ++i) { if (numbers[i+1] - numbers[i] === 1 && numbers[i+2] - numbers[i+1] === 1) { var begin = numbers[i]; while (numbers[i+1] - numbers[i] === 1) ++i; s.push(begin+'-'+numbers[i]); } else { s.push(numbers[i]); } } if ($(this).is('.t-li')) { this.parentElement.hidden = numbers.length === 0; $(this).text(s.join(',')+')'); } else $(this).text('('+s.join(',')+')'); }); }); } // Hide or show the elements expanded from the {{dsc ...}} template family. See documentation at // https://en.cppreference.com/w/Template:dcl/doc . // The revision markers are in the first cell of each dsc item. In the general case, the visibility // of a dsc item is control by a single revision marker. But if a specialized template is used, // and the amount of entity names in the first cell matches the lines of the revision markers, // then each line controls the visibility of a single entity name, and the dsc item is hidden only // if all the entity names are hidden. // If all the dsc items are hidden, then the corresponding headings are hidden as well. function handle_dsc() { $('.t-dsc').each(function() { var member = $(this).find('.t-dsc-member-div'); if (member[0]) { var lines = member.find('> div:nth-child(2) > .t-lines').children(); var mems = member.find('> div:first-child .t-lines').children(); if (lines.length !== mems.length) this.hidden = !should_be_shown(lines.children('.t-mark-rev')); else { lines.each(function(i) { var marker = $(this).children('.t-mark-rev'); mems[i].hidden = !should_be_shown(marker); marker.hidden = !should_be_shown(marker); }); this.hidden = all_hidden(mems); } } else { var marker = $(this).find('> td:first-child > .t-mark-rev'); this.hidden = !should_be_shown(marker); } }); $('.t-dsc .t-dsc-header').each(function() { var marker = $(this).find('> td > div > .t-mark-rev'); var lastheader = $(this).nextUntil(':not(.t-dsc-header)').addBack(); this.hidden = all_hidden(lastheader.nextUntil(':not(.t-dsc)')) || !should_be_shown(marker); }); var heading_selector = ['tr:has(> td > h5)', 'tr:has(> td > h3)']; $.each(heading_selector, function(i, selector) { $(selector).each(function() { var section = $(this).nextUntil(heading_selector.slice(i).join(',')); this.hidden = all_hidden(section.filter('.t-dsc')); }); }); $('.t-dsc-begin').each(function() { this.hidden = all_hidden($(this).find('.t-dsc')); }); } // Hide or show the navbar elements expanded from the {{nv ...}} template family. See documentation // at https://en.cppreference.com/w/Template:nv/doc . // A line of revision marker only controls a single entity name, even if it's expanded from // {{nv ln | ... }} that contains multiple lines. // If a heading contains a revision marker, that revision marker controls the visibility of the // heading and its corresponding contents; otherwise the heading is hidden when it is followed by // content elements, and all of them are hidden. function handle_nv() { $('.t-nv').each(function() { var marker = $(this).find('> td > .t-mark-rev'); this.hidden = !should_be_shown(marker); }); $('.t-nv-ln-table').each(function() { var lines = $(this).find('> div:nth-child(2) > .t-lines').children(); var mems = $(this).find('> div:first-child .t-lines').children(); lines.each(function(i) { var marker = $(this).children('.t-mark-rev'); if (mems[i]) mems[i].hidden = !should_be_shown(marker); marker.hidden = !should_be_shown(marker); }); this.hidden = all_hidden(mems); }); var heading_selector = ['.t-nv-h2', '.t-nv-h1']; $.each(heading_selector, function(i, selector) { $(selector).each(function() { var section = $(this).nextUntil(heading_selector.slice(i).join(',')); var marker = $(this).find('> td > .t-mark-rev'); if (marker[0]) { section.each(function() { this.hidden = this.hidden || !should_be_shown(marker); }); this.hidden = !should_be_shown(marker); } this.hidden = all_hidden(section.find('.t-nv-ln-table')); }); }); } // Hide or show the elements expanded from the {{rev ...}} template family. See documentation at // https://en.cppreference.com/w/Template:dcl/doc . // Borders are handled by class stdrev-rev-hide. function handle_rev() { $('.t-rev, .t-rev-inl').each(function() { this.hidden = !should_be_shown(this); }); } // Hide or show headings. // If the heading contains a revision marker, that revision marker controls the visibility of it // and its corresponding contents; otherwise, a heuristic is made: if the contents contain a dsc // list, and its revision-related contents are hidden, then the heading and all contents are hidden // as well. // The heuristic requires that handle_dsc() and handle_rev() have been called. function handle_headings() { var heading_selector = ['h5', 'h4', 'h3', 'h2']; $.each(heading_selector, function(i, selector) { $(selector).each(function() { var section = $(this).nextUntil(heading_selector.slice(i).join(',')); var marker = $(this).find('> span > .t-mark-rev'); if (marker[0]) { section.each(function() { this.hidden = this.hidden || !should_be_shown(marker); }); this.hidden = !should_be_shown(marker); } if (section.is('.t-dsc-begin') && !section.is(':not(p, .t-rev-begin, .t-dsc-begin)')) { var revisioned_content = section.find('.t-dsc, .t-rev, .t-rev-inl'); section.each(function() { this.hidden = this.hidden || all_hidden(revisioned_content); }); this.hidden = all_hidden(revisioned_content); } }); }); } // Hide or show <li> elements based on the contained revision markers. function handle_list_items() { $('li').each(function() { var marker = $(this).children('.t-mark-rev'); this.hidden = !should_be_shown(marker); }); } })(); |
Features include:
- hide section based on revision markers in the heading
- hide <li> based on its contained revision markers
- hide "Defined in header ..." when the corresponding entities are hidden
- implement renumbering inside {{v}}
- much shorter than P12's implementation! (~300LOC vs ~1800LOC)
Does it make sense to include this as an "official" gadget?
--223.3.167.101 10:25, 3 March 2019 (PST)
- We don't want to have two gadgets for the same thing. What does the current gadget do that this script doesn't, and vice versa? What caused the drastic shortening? T. Canens (talk) 11:07, 23 March 2019 (PDT)
- > What does the current gadget do that this script doesn't
- 1. be hosted on GitHub
- 2. have tests
- With regard to functionality, I don't know of any case that is handled better by Gadget-StandardRevision than by this script, but I don't have a thorough test.
- > and vice versa?
- All features mentioned above. Also, it does not have the problem reported below: Gadget-StandardRevision ignores all except the first revision marker in a row, and behaves unintuitively when the markers occupy more rows than the names in the dsc item. This script takes care to handle these cases better.
- > What caused the drastic shortening?
- Gadget-StandardRevision clones each of the elements that may be affected by the Gadget, and has a complex data structure to keep track of these elements and their clones. A lot of work is done to construct, manipulate, and debug this data structure. By contrast, this implementation directly manipulates the affected elements, which requires much less lines of code.
- --121.249.15.21 10:52, 24 March 2019 (PDT)
- The current gadget is also hosted on GitHub and has tests https://github.com/p12tic/cppreference-doc --Ybab321 (talk) 10:30, 26 March 2019 (PDT)
- Right, so I listed it as a thing that the current gadget do that this script doesn't :) --121.249.15.75 11:38, 26 March 2019 (PDT)
- The current gadget is also hosted on GitHub and has tests https://github.com/p12tic/cppreference-doc --Ybab321 (talk) 10:30, 26 March 2019 (PDT)
[edit] Updating the Embarcadero column
I'm a newly registered user, so cannot edit this page as it's under protection.
The Embarcadero column for C++14 and C++17 is out of date. The compiler supports all of C++14, and all of C++17 bar:
- Replacement of class objects containing reference members P0137R1
- Standardization of Parallelism TS P0024R2
- Elementary string conversions P0067R5
- Splicing Maps and Sets P0083R3
- Hardware interference size P0154R1
More info here: http://docwiki.embarcadero.com/RADStudio/Rio/en/Modern_C%2B%2B_Language_Features_Compliance_Status#C.2B.2B14_Features and http://docwiki.embarcadero.com/RADStudio/Rio/en/Modern_C%2B%2B_Language_Features_Compliance_Status#C.2B.2B17_Features
- yes, their new compilers are basically Clang: Embarcadero 10.1 is Clang 3.3, Embarcadero 10.3 (linked above) is Clang 5.0. But I suppose it's fair to update the table (for now, I updated the links below the table) --Cubbi (talk) 06:40, 8 March 2019 (PST)
[edit] Standard Revision gadget problems with C++20
It seems there are some problems with displaying (not displaying) features removed in C++20, On std::allocator page choosing C++20 Standard to be displayed, every removed feature is still on the list, marked as deprecated, information "removed in C++20" disappears. Is this template problem or widget problem? Kaznov (talk) 09:38, 15 March 2019 (PDT)
[edit] sizeof parameter can't be a C-style cast
I'm not able to make this change, but would like to suggest it.
sizeof's notes ought to say something like:
With form (2), expression cannot be a C-style cast, due to ambiguity with form (1). In other words, sizeof (char)+1 is parsed as (sizeof(char)) + 1, rather than sizeof((char)+1). — Preceding unsigned comment added by Myria (talk • contribs)
[edit] std::sort() should mention strict weak ordering requirements
The description of std::sort() does not mention that the comparison operator comp must define a strict weak ordering. Unless the standard has changed, it is undefined behavior to sort with a comparison function which does not define a strict weak ordering.
It also is probably worthwhile to explicitly point out that sorting with a comparison function that does not define a strict weak ordering is undefined behavior, and in fact in common implementations can lead to a crash or infinite loop, since it's a really commonly-encountered pitfall.
It may also be worthwhile pointing out that operator< does *not* define a strict weak ordering over floating point values due to NaN behavior, and so std::sort() may crash when applied to a vector of floating point values.
I believe that std::stable_sort() has implementation defined behavior rather than undefined when there's not a strict weak ordering, so it might also be worthwhile recommending using std::stable_sort() in such cases.
SethML (talk) 10:41, 9 April 2019 (PDT)
- cpp/algorithm/sort says "Compare must meet the requirements of Compare." and cpp/named_req/Compare explains strict weak ordering and all other requirements on the comparison function. I suppose it could be highlighted, something like "must meet the requirements of Compare, including the strict weak ordering requirement", but then it sounds like there are cases where the ordering is not included. Maybe a concise bad example would be worth adding.
- As for stable_sort, the actual requirement uses the word of power "shall"], so it's undefined to violate that for both sort and stable_sort. --Cubbi (talk) 11:12, 9 April 2019 (PDT)
- Indeed, I've been reading the standards and discovering these things. I'd had this assumption that stable_sort() was implementation-defined over poorly-ordered sequences, but it appears that it's actually undefined and could crash. In practice I think most implementations are a merge sort, which should have some reasonable behavior given input which isn't strict weak ordered. But the standard doesn't guarantee that, sadly.
- The phrasing in the standard is: For algorithms other than those described in alg.binary.search, comp shall induce a strict weak ordering on the values.
- I'd missed that the Compare requirement encoded the strict weak ordering requirement - that's pretty subtle. I do think that for all of the sort functions, it'd be nice to expand the compare bullet point, something like:
- * Compare must meet the requirements of Compare, including the strict weak ordering requirement. If it doesn't the behavior of X_sort is undefined.
- A bad example using floating point could be a good way to call out UB with floating point collections, since that's a serious gotcha.
- I find it also an interesting question what the behavior of lower_bound and friends is if passed a sequence that is not partitioned with respect to the value being searched for. The standard does not use the word "shall" - it says: All of the algorithms in this subclause are versions of binary search and assume that the sequence being searched is partitioned with respect to an expression formed by binding the search key to an argument of the comparison function. What is your interpretation of the result if the sequence is not partitioned - undefined behavior, or implementation defined?
- "implementation-defined" is an additional standard requirement, not made here. I would say "undefined". If you feel strongly enough about it, consider raising an editorial issue on whether 'assume' in [alg.binary.search]/1 means the same as 'shall' in [alg.sorting]/3, and what does it mean to violate it (ill-formed? undefined? unspecified?) --Cubbi (talk) 06:54, 10 April 2019 (PDT)
- I find it also an interesting question what the behavior of lower_bound and friends is if passed a sequence that is not partitioned with respect to the value being searched for. The standard does not use the word "shall" - it says: All of the algorithms in this subclause are versions of binary search and assume that the sequence being searched is partitioned with respect to an expression formed by binding the search key to an argument of the comparison function. What is your interpretation of the result if the sequence is not partitioned - undefined behavior, or implementation defined?
[edit] Definintion of synchronizes-with in cpp/atomic/memory order?
The page cpp/atomic/memory order tries to be fairly formal with defining the different types of memory ordering constraints, but a definition for "synchronizes-with" (which "inter-thread happens-before" depends on) appears to be missing.
[edit] more copy & pastable header
On all the pages at the top it says "Defined in <X>". I think it would be better to do "#include <X>" instead so I can copy & paste that into my code directly.
135.23.100.188 12:00, 21 April 2019 (PDT)Ben
[edit] Not all error_codes are platform-dependent
In https://en.cppreference.com/w/cpp/error error_condition and error_error are described as:
error_condition (C++11) holds a portable error code
error_code (C++11) holds a platform-dependent error code
But that doesn't seem to be correct. See for example https://akrzemi1.wordpress.com/2017/07/12/your-own-error-code/#comment-6921 or http://blog.think-async.com/2010/04/system-error-support-in-c0x-part-2.html
- The descriptions are from overviews in the standard, see syserr.errcode.overview and syserr.errcode.overview. If you want to add something about the actual usage, I think we can add a "Notes" section to describe it. (By the way, the second article was written before C++11 so I doubt whether it is useful now.) --Fruderica (talk) 07:45, 27 April 2019 (PDT)
[edit] open source libs
How to add reference to open source lib? (Alex25 (talk) 01:20, 28 April 2019 (PDT))
[edit] Improving this site
I'm hardly a new user... can't I get edit rights (back)? CarloWood (talk) 09:18, 28 April 2019 (PDT)
[edit] BNFLite
Could you add nice BNFLite parsing h-library ( https://github.com/r35382/bnflite) into Text::Parse section
[edit] Language support page: list library support with the library name not the compiler name
The language support page lists compiler names in the list of library features. In a lot of Linux distributions, Clang will by default use GCC's libstdc++ instead of LLVM's libc++, which means that the relevant column to look at in that table for support when using Clang is the GCC column, not the Clang column. Likewise, clang-cl will use MSVC's standard library by default. (I think Intel's compiler behaves similarly to Clang in this regard, and indeed probably several other compilers in the table are not coupled to a particular standard library implementation.)
The current table structure seems less helpful than it could be.
Suggestion: rename the GCC column to libstdc++ and the Clang column to libc++; remove the columns for compilers that don't have their own standard library implementation; add introductory text explaining which standard library each compiler uses by default.
zygoloid (talk) 17:12, 4 May 2019 (PDT)
- this has been suggested as far back as 2016 Talk:cpp/compiler_support#Splitting_and_folding the_table and I don't think there is any opposition. Someone just needs to volunteer. --Cubbi (talk) 06:08, 6 May 2019 (PDT)
- Now I have placed core language features and library features into different tables, and renamed the columns when listing library features. However I think the introductory might be a hard work, since the compilers' default usage of standard library implementation is not well-documented. --Fruderica (talk) 21:54, 6 May 2019 (PDT)
[edit] Equivalence of the signature of function objects
Hi,
the documentation of (e.g.) std::accumulate says:
op The signature of the function should be equivalent to the following:
Ret fun(const Type1 &a, const Type2 &b);
The signature does not need to have const &.
When is a signature "equivalent" to the above? 2001:B01:2404:4:0:0:0:57 23:49, 9 May 2019 (PDT)
- This is handwaving vigorously. The basic requirement is that a set of expressions must work. But of course that's a bit abstract and we want to show what a function (object) that meets the requirement should look like. Hence the weasel-wording. Perhaps we should rephrase the requirements in terms of the required expressions, and then show sample signatures as examples? T. Canens (talk) 20:23, 17 May 2019 (PDT)
[edit] operator :: – ( I cannot edit https://en.cppreference.com/w/Talk:cpp/language/operator_precedence where it belongs to)
At https://en.cppreference.com/w/cpp/language/operator_precedence the token ::
that is used to build nested names is listed as an "operator". But AFAIK this token is not an operator (or a very special one).
Because for any (binary) operator ★ the term A★B★C
either means (A★B)★C
_or_ A★(B★C)
and you might add (…) to change the meaning.
But for :: you can't do this, because A::(B::C)
does not compile, and (A::B)::C
compiles, but is parsed as a type cast of ::C
into the type A::B
. :-/
What do you think? Should it be changed or at least mentioned? --Roker (talk) 04:01, 13 May 2019 (PDT)
- the whole table is a loose approximation of expression grammar in human-readable terms of "precedence" and "associativity". These terms do not appear anywhere in the language specification, they are invented by the authors of the table. In the expression grammar, :: combines identifiers into primary expressions, so inasmuch as the grammar can be expressed in those terms, it has the "highest precedence". We could drop it, but then people used to seeing precedence tables from other sources such as enwiki:Operators_in_C_and_C++#Operator_precedence would say cppreference's table is incomplete and add it back. --Cubbi (talk) 06:40, 13 May 2019 (PDT)
- They can already say that since cppreference's table does not include const_cast et al, though.
- OTOH, the standard calls :: an operator in [over.oper]/3. --D41D8CD98F (talk) 11:06, 14 May 2019 (PDT)
[edit] Add reference to paragraph about automatically generated class member functions
Hi there.
In https://en.cppreference.com/w/cpp/language/classes, I suggest in the last paragraph we add references to the rule of zero/three/five.
The very last sentence says:
"Some member functions are special: under certain circumstances they are defined by the compiler even if not defined by the user."
This would be an optimal place to refer to the rule of zero/three/five (link: https://en.cppreference.com/w/cpp/language/rule_of_three).
217.10.52.10 05:02, 13 May 2019 (PDT) André Malcher
[edit] Help to translate
Eu gostaria de ajudar a traduzir as páginas para o português do Brasil, por que tem grande diferenças do de Portugal.
Gostaria de saber como posso fazer isso?
[edit] Add argument types in the examples
https://en.cppreference.com/w/cpp/io/c/fprintf
Stupidly enough, despite the extensive examples, there is none using the argument types (e.g. %lu)
[edit] AI using C++...
[ai.stackexchange.com/questions/6185/why-does-c-seem-less-widely-used-in-ai] is the source of the following. I have inserted links to the libraries web sites. You don't need a powerful language for programming AI. Most of the developers are using libraries like Keras,[keras.io] Torch [torch.ch], Caffe,[caffe.berkeleyvision.org] Watson [cloud.ibm.com/developer/watson/dashboard], TensorFlow,[www.tensorflow.org] etc. Those libraries are highly optimized and handle all the though work, they are built with high performance languages, like C. Python is just there to describe the neural network layers, load data, launch the processing and display results. Using C++ instead would give barely no performance improvement, but would be harder for non-developers as it require to care for memory management. Also, several AI people may not have a very solid programming or computer science background.
Another similar example would be game development, where the engine is coded in C/C++, and, often, all the game logic scripted in a high level language. Ian Martin Ajzenszmidt (talk) 05:39, 18 May 2019 (PDT)
[edit] Add See also: reference to <iomanip> from std::string?
Just a stray thought for improved navigation. For new C++ users that find themselves at [std::basic_string](https://en.cppreference.com/w/cpp/string/basic_string) and the next place many would need to go a majority of the time would be to <iomanip>. Would it be worth adding a ***See Also:*** reference to <iomanip>. Especially for those who do not yet know <iomanip> exists. Drankinatty (talk) 18:26, 18 May 2019 (PDT)
[edit] cpp/language/operator_comparison
first sentence of the the section Notes currently is:
Because these operators group left-to-right, the expression a<b<c is parsed (a<b)<c, and not a<(b<c) or (a<b)&&(b<c).
but the following would be clearer to understand:
Because these operators group left-to-right, the expression a<b<c is parsed (a<b)<c, and neither a<(b<c) nor (a<b)&&(b<c).
[edit] where can be donations be sent?
Hello ! I read about the donations, can you give me please more informations about whre can the donations be made? it will be very usefull. Thanks ! Sorry for disturbing the discussion page -Giani
- You can support cppreference.com from the "Support us" link at the bottom of the page, which goes to a merch store. Studyingegret (talk) 01:45, 16 July 2024 (PDT)
[edit] contradiction in definition of std::filesystem::weakly_canonical
In the description of std::filesystem::weakly_canonical, it is stated that the parameter p must be an existing path. This is in contradiction with the description of the function std::filesystem::weakly_canonical, that states that p can consist of an existent left-hand-side and a non-existent right-hand-side.
[edit] Parallelism TS 2
- https://en.cppreference.com/w/cpp/experimental/simd needs to be linked from https://en.cppreference.com/w/cpp/experimental/parallelism_2.
- https://en.cppreference.com/mwiki/index.php?title=cpp/experimental/simd/abi_for_size needs to be renamed (as happend in the WD before the TS was published) to simd_abi::deduce.
- Most of the simd documentation needs to either be updated to TS state or written.
- I could help (author of that part of the TS).
Vir (talk) 03:12, 27 May 2019 (PDT)
[edit] suggestion for the Private Inheritance section
this sentence is hard to read:
Using a member offers better encapsulation and is generally preferred unless the derived class requires access to protected members (including constructors) of the base, needs to override a virtual member of the base, needs the base to be constructed before and destructed after some other base subobject, needs to share a virtual base or needs to control the construction of a virtual base.
this is much easier, using a list:
Using a member offers better encapsulation and is generally preferred unless the derived class: --requires access to protected members (including constructors) of the base --needs to override a virtual member of the base --needs the base to be constructed before and destructed after some other base subobject --needs to share a virtual base or needs to control the construction of a virtual base
75.142.108.70 14:01, 2 June 2019 (PDT)
[edit] Suggested addition for std::time page
Please add links to the following pages in the "See also" section of https://en.cppreference.com/w/cpp/chrono/c/time
https://en.cppreference.com/w/cpp/chrono/c/asctime https://en.cppreference.com/w/cpp/chrono/c/strftime
139.181.7.34 16:30, 4 June 2019 (PDT)
[edit] the headline for the non-throwing deletes is incorrect
functions 9-12 are headlined as placement versions, whereas they are non-throwing versions.
- new(nothrow) is placement-new by expr.new/15 --Cubbi (talk) 05:07, 6 June 2019 (PDT)
- now I see, cpp/memory/new/operator_new calls them "replaceable non-throwing", while cpp/memory/new/operator_delete calls them "replaceable placement".. Perhaps "non-throwing" is more user-friendly even if all of them are actually non-throwing --Cubbi (talk) 06:41, 6 June 2019 (PDT)
[edit] Only for multidimensional arrays?
I think the description should read "(potentially multidimensional) array" instead of "multidimensional array".
[edit] Can a standard exception object embed a fixed-size array?
The documentation for e.g. std::runtime_error, at
<https://en.cppreference.com/w/cpp/error/runtime_error>,
states:
"Because copying std::runtime_error is not permitted to throw exceptions, this message is typically stored internally as a separately-allocated reference-counted string."
Would it be OK to store the message into an array data member? That means that the string could have to be truncated, so the question is whether having a maximum length falls under possible implementation-defined limits. 37.182.205.198 03:06, 13 June 2019 (PDT)
- The string cannot be truncated because of the post-condition. Though I think that constructors of
std::runtime_error
takingconst char*
andconst std::string&
are still permitted to throw exception if the string is too long, and an array ofchar
embedded in the exception object is also permitted --Fruderica (talk) 03:55, 13 June 2019 (PDT)
[edit] std::size_t error in example
Reverse iteration. Unsigned variable taking values lower than 0.
for (std::size_t i = a.size()-1; i < a.size(); --i)
Should be:
for (std::size_t i = a.size()-1; i >= 0; --i)
- std::size_t is an unsigned integer type, so
i >= 0
always holds and the loop you suggested is endless. On the other hand, ifi == 0
then--i
makei
equals to the maximum value ofstd::size_t
which is almost always larger thana.size()
, so the loop will reach its end. If you don't like this, something like for (std::size_t i = a.size(); i != 0;) { --i;/*...*/} might be useful. --Fruderica (talk) 04:56, 21 June 2019 (PDT)
[edit] Typo on std::iterator page
Hi,
In the example section of the std::iterator page it says '.. _a_ input iterator ..' which should be '.. _an_ input iterator ..'.
Thanks for the truly excellent resource that is cppreference.
Best regards,
Kris van Rens 5.132.118.36 13:44, 22 June 2019 (PDT)
[edit] Enum syntax: trailing semicolon
It appears that on the enum declaration page, a trailing semicolon is missing at various places for the enum declarations.
[edit] Replace dead link in rule of three page with archive.org link
The link to the original source for the "rule of zero" on the page https://en.cppreference.com/w/cpp/language/rule_of_three is dead.
Perhaps change https://rmf.io/cxx11/rule-of-zero to https://web.archive.org/web/20160602100235/https://rmf.io/cxx11/rule-of-zero/
73.8.19.235 09:19, 10 July 2019 (PDT)joe
[edit] errno and strto* examples
On some examples, like strtol, errno is not reset before calling the function and is checked after an intermediate call to other functions, such as printf, which can set errno itself.
Although it is not relevant for the correct execution of the example, IMHO those code snippets should be a vehicle for promoting good practices. So I suggest to clear errno before calling strto* and test (or save) it immediately after the call.
79.151.6.162 10:19, 11 July 2019 (PDT)oscarfv
[edit] Subsume is synonym for implies.
On TS variant of concepts at: https://en.cppreference.com/w/cpp/experimental/constraints
You have inconsistency in your definitions/use of the word subsumes. Subsumes is synonym for implies by your first definition. (and also by C++20 standard version of concept https://en.cppreference.com/w/cpp/language/constraints)
1) "Concept P
is said to subsume concept Q
if it can be proven that P
implies Q
"
2) "A
subsumes a conjunction A&&B
and does not subsume a disjunction A||B
"
But
Mathematically in truth/boolean logic this is tautology for conjunction (always true):
A&&B
impliesA
and also always
A&&B
impliesB
so by first definition of word 'subsume' the second statement above should be other way around
A&&B
subsumesA
and also mathematically for disjunction (boolean logic):
A
impliesA||B
and also
B
impliesA||B
Now replace word implies for subsumes in those statements and you get contradiction again to your second statement 2).
Also note:
A||B
does not implyA
A||B
does not implyB
so again does not subsume.
On another note: You derive class to model 'is-a' relationship or subset relationship. You narrow down original big class of animals.
class Cat:Animal {}
Cat is an animal. Set of cats is subset of set of all animals.
Or you have implication "x is a cat implies x is an animal" , but not otherway around 'x is animal' does not imply 'x is a cat'. In concept language: Cat is additional constraint on top of animal. (Moveable and meowavle) and additional constraint makes class smaller subset and smaller subset means. So you either say Animal set subsumes Cats sub-set. Or you use 'subsume' for the characteristics (like in concepts). Cat characteristic subsumes Animal characteristics (x is a cat assumes/implies/subsumes x is a living being).
[edit] @ sign is displayed in place of overloaded operators
Sorry about the previous message, I accidentally posted an edited page instead of the suggestion.
Edit suggestion: @ sign is being displayed instead of operators !, << and ++ in Overloaded Operators section.
[edit] overload resolution links in using-declaration
In the inheriting constructors section of the using_declaration it would be great to add a link when overload resolution is mentioned.
[edit] Unqualified name lookup->Class definition
I think a, c is incorrect because of class scope and his accessing rules - all names defined in class is available in entire class even if declaration is put below instruction of use.
d - if class is nested into another class then entire outer class will be searching and if name will still not found then local scope until definition class - because function accessing rules.
- the rules you're describing are a little lower, in cpp/language/unqualified_lookup#Member_function_definition --Cubbi (talk) 08:23, 2 August 2019 (PDT)
[edit] main() is indented 4 spaces. Unlike the rest. Please make that 2 spaces.
main() is indented 4 spaces. Unlike the rest. Please make that 2 spaces.
PS Can't I get edit rights? I'm not vandalizing, so...
[edit] C fwrite missing error behaviour regarding file position.
If an error occurs, the resulting value of the file position indicator for the stream is indeterminate.
13.236.57.85 01:41, 6 August 2019 (PDT)
[edit] inconsistent find/rfind description
I don't think "find characters" is good wording for find on the main page of basic_string, should be "find substring" (or "find character sequence" as it's put in https://en.cppreference.com/w/cpp/string/basic_string/find) in order to avoid confusion with find_first_of. Also find/rfind titles should be consistent imo, "find the first/last occurrence of a substring" seems to be a good fit
https://en.cppreference.com/w/cpp/string/basic_string
find: "find characters in the string" rfind: "find the last occurrence of a substring"
180.183.72.126 22:38, 6 August 2019 (PDT) Vitaly
[edit] Template:cpp/container/lower bound
Add "(i.e. greater or equal to)" after "that is not less than" (like the text on cpp/algorithm/lower bound).
[edit] Suggestion for clarity
The description for the return value contains the phrase, "Nonzero integral value if arg is negative." While technically correct, I think it's worth considering changing "integral" to "integer." ZephyrCubic (talk) 14:34, 11 October 2023 (PDT)
- this is about c/numeric/math/signbit which is actually shown in C99 and C11 synopsis with a return type of type int, so I agree, "integer" would be more to the point. --Cubbi (talk) 20:28, 11 October 2023 (PDT)
[edit] Forward declaring enums in C
c/language/enum says "...there are no forward-declared enums in C". However, C23 in 6.7.2.2 /6 explicitly allows a forward-declaration of an enum as long as the underlying type is specified ("An enum specifier of the form enum identifier enum-type-specifier may not appear except in a declaration of the form enum identifier enum-type-specifier ; ...") --2A02:586:292B:EA0E:E08F:CE97:FFEA:E15E 06:20, 15 October 2023 (PDT)
- Forgot to mention that the example at 6.7.2.2/18 shows exactly this. --2A02:586:292B:EA0E:E08F:CE97:FFEA:E15E 06:47, 15 October 2023 (PDT)
- Add to this c/language/declarations which says that every declaration of an enum is a definition. That should be tagged as until C23. 2A02:1388:9D:F494:0:0:5403:3A5F 00:41, 25 January 2024 (PST)
[edit] Missing redirects
cpp/numeric/math/HUGE_VALF and cpp/numeric/math/HUGE_VALL redirect to cpp/numeric/math/HUGE_VAL. c/numeric/math/HUGE_VALF and c/numeric/math/HUGE_VALL should similarly go to c/numeric/math/HUGE_VAL.--2A02:586:292B:EA0E:30A6:F697:75DA:1AC1 11:28, 15 October 2023 (PDT)
The use of the comma operator in the example code at https://en.cppreference.com/w/Template:cpp/container/constructor is unnecessary and confusing for inexperienced c++ developers Alanbirtles (talk) 23:22, 17 October 2023 (PDT)
- It's kinda funny yeah, but you gotta get that comma operator experience somewhere right? Otherwise you'll be doomed to be inexperienced forever! But yeah, it's a bit comma abusive, not against changing it to two statements --Ybab321 (talk) 02:26, 18 October 2023 (PDT)
- the comma has a lot of cute semi-idiomatic uses (maybe I should list them on cpp/language/operator_other#Built-in_comma_operator - the example there is just showing what it does, but not what it's good for ).. As for this example, I think it's a good idea to keep the container printing code tight so that more of the example can be about the topic of the page. Personally I'd just space-separate them with the dangling space in the end. --Cubbi (talk) 10:37, 18 October 2023 (PDT)
[edit] std::expected doesn't work on clang-16 and clang-17
std::expected not available on clang-16 or clang-17
clang-16 compile failure:
https://github.com/acgetchell/CDT-plusplus/actions/runs/6621477342/job/17985496207
clang-17 compile failure:
https://github.com/acgetchell/CDT-plusplus/actions/runs/6621477365/job/17985496236
gcc-12 compile success:
https://app.travis-ci.com/github/acgetchell/CDT-plusplus/jobs/612081167
gcc-13 compile success:
https://github.com/acgetchell/CDT-plusplus/actions/runs/6621477345/job/17985496195
It also compiles successfully on macOS with libc++ included with Xcode 15.
[edit] Calling clear after istringstream::str
I think there should be some note on `https://en.cppreference.com/w/cpp/io/basic_istringstream/str` to call `istringstream::clear` after setting a new input string by `istringstream::str`. Otherwise, if you've read on the preceding string to the end, and the eof or fail bits are set, reading from the new string will fail. 2003:DC:AF3C:5600:405F:3FE8:146F:36E7 08:32, 25 October 2023 (PDT)
- Hm, this is a general property of reaching the end of a stream and then reusing it. Such a note would apply to std::istream::seekg, std::ifstream::open and std::ispanstream::span, so probably worth writing a transclusion for. Tempting to just put
clear()
into the code examples... In any case, I agree, that would be a good note --Ybab321 (talk) 10:39, 25 October 2023 (PDT)- there's some variety here; cpp/io/basic_ifstream/open clears all flags (but remember to close before reopening), cpp/io/basic_istream/seekg clears EOF but not others. I could see a Note on cpp/io/basic_istringstream/str "unlike ifstream::open, non-const overload of str does not clear...". And I suppose a note on ifstream::open to close before reopen. --Cubbi (talk) 12:29, 25 October 2023 (PDT)
[edit] Add to pages about language features what compilers support said features
The current compiler support page albeit helpful is hard to navigate and find specific features and what compilers support them and the version of the compiler the support is offered at. I'd be extremely helpful if right before the see more section of the page there was also a table that shows compiler support for the most major compilers for the specific feature the page is about. Or in the very least a link that sends to you to the location of said feature in the compiler support page.
- What you probably want is something like the "Browser compatibility table" in MDN. Unfortunately, cppreference is not backed by any compiler vendor (unlike MDN), so there is no mechanism to keep track of the compiler implementation status except manual updates by user edits. Compatility tables spreading across the site are difficult to maintain, since users need to navigate to many different pages to update the compiler implementation status.
- What the pages currently have are the "Notes" sections, which contain the notable compiler incompatibilities and these feature-test macro tables (since C++20). The way recommended by the C++ standard to check whether a language/library feature is implemented is to use the feautre-test macros. --Xmcgcg (talk) 22:54, 26 October 2023 (PDT)
- This can be done with a script. I've actually written one and have been using it since last year, and I think this script is good enough to help readers. See Talk:Main Page#Proposal: add User:D41D8CD98F/append-support-info.js for all users. --D41D8CD98F (talk) 23:44, 26 October 2023 (PDT)
- This can be done with a script. I've actually written one and have been using it since last year, and I think this script is good enough to help readers. See Talk:Main Page#Proposal: add User:D41D8CD98F/append-support-info.js for all users. --D41D8CD98F (talk) 23:44, 26 October 2023 (PDT)
... in the very least a link that sends you to the location of said feature in the compiler support page ...
- Exactly this can be done relatively easily. Actually, this is almost what was already done with links to general FTM tables. I only need to update {{ftm}}/{{feature test macro}} templates (to deduce a proper link from known ftm and rev) and add an anchor to each row of compiler support table, based on their FTM (this means creating only one more template alike {{tta}} = Teletype Text + Anchor, etc). No need to update individual FTM-tables (spread across pages). The main work then is to update compiler support tables by filling one additional internal field per each target entry. ⇒ No interference with server cache, no javascript, no html-injection (which is great but, maybe, not all users are interested in compiler support stuff). And the maintenance would be relatively cheap w.r.t. manpower, but not as cheap as with script-solution.) --Space Mission (talk) 15:44, 27 October 2023 (PDT)
[edit]
Relevant pages:
- std::error_code::message
- std::error_category::message
- std::system_error because of std::system_error::what
Because these types use std::strerror internally, they are not thread-safe (this is documented on the page of std::strerror).
Here's just one implementation from GCC: [1] [2]
I think it should be documented that using these types is only appropriate in single-threaded applications!
--84.190.143.49 08:22, 3 November 2023 (PDT)
- Glibc has thread-safe strerror, as does musl and newlib. We can say that libstdc++'s error_category::message is not thread-safe if used with a libc that is not well-known, but I doubt whether anyone do this in practice, and whether libstdc++ officially supports such usage. --D41D8CD98F (talk) 19:47, 3 November 2023 (PDT)
- In glibc, this was only added 2020-05-14 [3] and so was first released in glibc 2.32 [4]. For example, debian oldstable and oldoldstable which still are supported LTS versions use glibc versions older than this [5][6]. Many proprietary/legacy systems probably use older and will continue to do so for many years. That should be considered too apart from just the possibility of exotic libc implementations. 2003:E8:2726:6D00:80E3:B475:E170:AF01 13:12, 4 November 2023 (PDT)
[edit] memory_order should mention that read-modify-write operations always read the last value
I searched in cppreference, but it seems that currently there's no page mentioning this.
https://eel.is/c++draft/atomics#order-10
[edit] Should decltype
be added to the list of operators?
I argue that it should, for consistency with c/language/typeof which is referred to as the "typeof operator" in C23 6.7.2.5. Note that there is precedent for calling decltype
an operator, see n2343. If you disagree then at least remove typeof
from c/language/operator_other and remove the name typeof operator from c/language/typeof since it would be weird if one is an operator and the other is not.--2A02:586:292B:EA0C:91D9:325:3A52:19C1 11:38, 4 November 2023 (PDT)
-
typeof
should be removed from the C operator list. The term “typeof operators” is just a collection oftypeof
andtypeof_unequal
. --Xmcgcg (talk) 01:07, 5 November 2023 (PDT)
[edit] Type punning using unions in C89/C90
The page https://en.cppreference.com/w/c/language/union says the following:
> If the member used to access the contents of a union is not the same as the member last used to store a value, the object representation of the value that was stored is reinterpreted as an object representation of the new type (this is known as type punning). If the size of the new type is larger than the size of the last-written type, the contents of the excess bytes are unspecified (and may be a trap representation). Before C99 TC3 (DR 283) this behaviour was undefined, but commonly implemented this way.
The highlighted part looks wrong to me, because C89 clearly defines this as implementation-specified behaviour, not undefined one. See 3.3.2.3: Structure and union members (or 6.3.2.3 in C90), here's an excerpt:
> With one exception, if a member of a union object is accessed after a value has been stored in a different member of the object, the behavior is implementation-defined.
It's also worth noting that in C99 this sentence was removed, and I have no idea, why. The TC3 for C99 was issued noticeably later.
See in addition these SO answers:
https://stackoverflow.com/questions/52290456/is-the-following-c-union-access-pattern-undefined-behavior/52291386#52291386
https://stackoverflow.com/questions/25664848/is-it-allowed-to-use-unions-for-type-punning-and-if-not-why/25672839#25672839
https://stackoverflow.com/questions/55010795/type-punning-between-integer-and-array-using-union/55012433#55012433
https://stackoverflow.com/questions/11373203/accessing-inactive-union-member-and-undefined-behavior/11373277#11373277
Also, why the "References" sections refer to C89/C90 standard as ISO/IEC 9899:1990, but provide chapter numbering as in ANSI X3.159-1989? Although the names of the chapters themselves are given without capitalization, as it's in the ISO document, not ANSI one.
--Cher-nov (talk) 03:25, 1 December 2023 (PST)
[edit] Template:cpp/compiler_support/dump incorrect usage of __has_cpp_attribute
At Template:cpp/compiler_support/dump, we can read
#ifdef __has_cpp_attribute # define COMPILER_ATTRIBUTE(expect, name) { #name, __has_cpp_attribute(name), expect }, #else # define COMPILER_ATTRIBUTE(expect, name) { #name, COMPILER_VALUE_INT(name), expect }, #endif
but unfortunately that is an incorrect usage of __has_cpp_attribute
.
Quoting cpp/feature_test:
__has_cpp_attribute
can be expanded in the expression ofand
- if
elif . It is treated as a defined macro by,
- ifdef
ifndef ,elifdef ,elifndef (since C++23) and defined but cannot be used anywhere else.
And thus __has_cpp_attribute(name)
cannot be used in the definition of another macro, like COMPILER_ATTRIBUTE
.
gcc and clang will accept that code, but MSVC will not. See on compiler explorer: https://godbolt.org/z/6j6Mexeee
-- Lrineau (talk) 02:57, 21 December 2023 (PST)
- Here is more conformant implementation: https://godbolt.org/z/jns9EEGab. The obvious drawback is that it requires +50+LOC, which is quite a lot for this "example". Currently, only more light-weight fix is applying to code - a plain check for gcc/clang, so msvc will also run, but w/o attributes info support. --Space Mission (talk) 16:51, 22 December 2023 (PST)
[edit] __has_c_attribute has an incorrect description
The description of __has_c_attribute in c/language/attributes should be exactly the same as the description of __has_cpp_attribute from cpp/feature_test. However, the fact that __has_c_reference can appear in #elifdef and #elifndef directives was not copied over despite these directives existing in C23. --2A02:586:292B:EA0C:5D4A:A41:7147:ECE7 06:00, 21 December 2023 (PST)
[edit] pointer to member `operator->*`
Hi everyone,
I'd like to add sqlite_orm to the list of EDSL libraries that overload the pointer-to-member `operator->*` in a meaningful way
The addition should come after cpp.react in Section "Rarely overloaded operators" of page https://en.cppreference.com/w/cpp/language/operators#Rarely_overloaded_operators.
Thanks, Klaus Triendl.kj (talk) 08:55, 25 December 2023 (PST)
[edit] I can't add even links to blogs now
Some discussion with few examples:
https://devtut.github.io/cpp/std-optional.html
https://www.codingninjas.com/studio/library/std-optional
Many points aren't mentioned inany way at std::optional. std::optional isn't the newest now...
I can't link an article like [[std::optional]] as well.
I can't use talk pages. I can't register. 95.26.137.42 00:28, 5 January 2024 (PST)
[edit] Compiler support is missing at individual pages.
Keep just 1 row from Compiler support for C++17 at std::optional.
Some reasonable duplication is helpful here. 95.26.137.42 01:24, 5 January 2024 (PST)
[edit] Programming languages, implementations, variants and extensions
I support both C and C++ together as they are related.
I am missing several C++ variants.
I prefer to have one MediaWiki namespace per each. 95.26.137.42 01:36, 5 January 2024 (PST)
[edit] Asterisks aren't clear and hovers aren't mobile, print friendly
I can't access notes at pages like cpp/compiler support.
- × The incomprehensible blob from the previous post was deleted.
- Please repeat using normal UTF-8 text, not "jquery", if your post had any value. --Space Mission (talk) 20:55, 5 January 2024 (PST)
[edit] Unsequenced and reproducible used incorrectly
While one could make the argument that it's obvious, I think c/language/attributes/unsequenced should mention what happens in the case the attributes get appled incorrectly. The standard says:
"[...] if a definition that does not have the asserted property is accessed by a function declaration or a function pointer with a type that has the attribute, the behavior is undefined"
so something to that effect should be added to the page. --85.74.201.230 06:02, 7 January 2024 (PST)
[edit] aligned_alloc() and alignments less than sizeof(void *)
The page for aligned_alloc()
claims that
- Fundamental alignments are always supported.
just after observing that
- As an example of the "supported by the implementation" requirement, POSIX function
posix_memalign
accepts any alignment that is a power of two and a multiple of sizeof(void *), and POSIX-based implementations ofaligned_alloc
inherit this requirements.
The two appear to be mutually exclusive — under the POSIX model, alignments less than sizeof(void *) are not valid, which would mean that trying to use alignments of 1, 2 or 4 on a machine with 64-bit pointers won't work — though 1, 2 and 4 are "fundamental alignments".
Additionally, I can't find wording in any of the C standards to support the claim that "fundamental alignments are always supported". All it says on that subject is that
- The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and size less than or equal to the size requested.
i.e. the allocation may fail, and one of the reasons it may fail is an unsupported alignment, for instance in a POSIX-based implementation, one smaller than sizeof(void *).
Al45tair (talk) 03:31, 8 January 2024 (PST)
- DR 460 lays out the standard wording (and is somewhat relevant too). Does seem like posix_memalign isn't a conforming aligned_alloc --Ybab321 (talk) 12:25, 9 January 2024 (PST)
[edit] (Technical) MediaWiki version
According to Special:Version, this wiki is running on MediaWiki version 1.21.2, which has reached end-of-life since 2014! If we upgrade it, we'll be able to use have security fixes, in-site search and the awesome WikiEditor(not visual). Is there any reason the software is so outdated? Aaron Liu (talk) 11:32, 14 January 2024 (PST)
- This site depends on a bunch of home-made extensions (e.g. AutoLinker and CustomList) and skins (Cppreference and Cppreference2, the latter being the default skin). I guess at least some of them are not compatible with the latest MediaWiki. --D41D8CD98F (talk) 03:42, 15 January 2024 (PST)
- Assuming only extensions by Mr. Kanapickas are homemade:
- NativeSvgHandler has an updated, supported version.
- AddBodyClass has a pull request to update it.
- Skins can probably be straight up used in the new version of MediaWiki and at most output warning messages about deprecated hooks, as was the case with Cologne Blue.
- AutoLinker and CustomList are indeed not updated yet. Aaron Liu (talk) 06:52, 15 January 2024 (PST)
- Assuming only extensions by Mr. Kanapickas are homemade:
- Note also that, as pointed out in #Comment for vandalism, extension:Abusefilter would become available with such an upgrade. That extension might even allow the wiki to open again. 95.164.181.95 04:14, 21 July 2024 (PDT)
[edit] user: Egorpugin
Requesting edit rights. Need to do some fixes to compiler support page.
- As a quick alternative, could you list the proposed changes here so we can integrate them. --Space Mission (talk) 05:04, 15 January 2024 (PST)
[edit] Title in Copy elision page is confusing
Related page: https://en.cppreference.com/w/cpp/language/copy_elision
Title: 1.2 Non-mandatory copy/move elision Later in this chapter, it is indicated that from C++17 on, the optimization is mandatory. As such, similar to the inline correction for C++11, this should have an inline correction indicating that the `non-` is only until C++17 — Preceding unsigned comment added by JVApen (talk • contribs) 00:33, 15 January 2024
- Only unnamed return value optimization is mandatory since C++17. I've adjusted the markup to clarify that. --D41D8CD98F (talk) 03:50, 15 January 2024 (PST)
[edit] Incorrect note describing sizeof with VLA types
This page c/language/array#Notes provides the following example:
int n = 5; size_t sz = sizeof(int (*)[n++]); // may or may not increment n
which says that the expression sizeof(int (*)[n++]) may or may not increment n. This should never increment n, considering that the expression is a constant expression.
Section 6.5.3.4 "The sizeof and _Alignof operators" Paragraph 2 ISO/IEC 9899:2018
The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type. The size is determined from the type of the operand. The result is an integer. If the type of the operand is a variable length array type, the operand is evaluated; otherwise, the operand is not evaluated and the result is an integer constant.
The type int (*)[n++] is not a variable length array type (it is variably modified but this is different from being a variable length array type) so the operand is not evaluated and the result is an integer constant. This can be demonstrated with a statement that requires the expression to be an integer constant expression:
int n = 5; enum {E = sizeof(int (*)[n++])};
A better example would be:
int n = 5; int m = 5; size_t sz = sizeof(int (*[n++])[m++]); // n is always incremented // m may or may not be incremented
- looks like I put that in 9 years ago trying to illustrate 6.7.6.2p5 which doesn't appear to restrict itself to VLAs or even evaluated operands, but, yes, this makes more sense, OTOH I am not sure there are compilers that skip side effects and maintaining an example on that note at all may be elevating obscure trivia. I'll put your example in though. --Cubbi (talk) 16:06, 16 January 2024 (PST)
[edit] Suggestion to update c/preprocessor/conditional
I would suggest to add phrasing to c/preprocessor/conditional that indicate that operators that involve types (type casts, sizeof) are not allowed inside #if conditions.
[edit] Anchor bug in cpp/compiler support
In the page cpp/compiler support, the C++23 core language features link anchors to the C++26 section. This is due to what looks like a copy/paste error: the C++23 anchor is above the C++26 section and there is no anchor above the C++23 section. The page is locked due to vandalism, hence I am posting here.
Md5i (talk) 18:40, 23 January 2024 (PST)
- ✔ Fixed: cpp/compiler support. Thanks.) --Space Mission (talk) 01:07, 24 January 2024 (PST)
[edit] FMA modification of macros
I can't edit the page, but the page on fma says, "f the macro constants FP_FAST_FMA, FP_FAST_FMAF, or FP_FAST_FMAL are defined, the function std::fma evaluates faster (in addition to being more precise) than the expression x * y + z for float, double, and long double arguments, respectively." This is incorrect. Either the macro order must be changed to "P_FAST_FMAF, FP_FAST_FMA, or FP_FAST_FMAL" or the types must be changed to "double, float, and long double."
https://en.cppreference.com/w/cpp/numeric/math/fma
[edit] Comma expressions in initializers
cpp/language/initialization says that the expressions used in initializations cannot be comma expressions. That should be changed to unparenthesized comma expressions since parenthesized comma expressions are allowed in that context 2A02:1388:9D:F494:0:0:5403:3A5F 23:44, 24 January 2024 (PST)
- Parenthesized expressions are classified as primary expressions. If a parenthesized expression is also accepted in certain context, the wording will include “(possibly parenthesized)” or “(possibly enclosed in parentheses)”. --Xmcgcg (talk) 02:30, 25 January 2024 (PST)
- I guess no change is needed then. Still, the standard includes a note that makes it explicit and we also mention parentheses explicitly in cpp/language/operator_member_access#Built-in_subscript_operator so I still think it should be added --2A02:1388:9D:F494:0:0:5403:3A5F 06:20, 25 January 2024 (PST)
[edit] Add a new library
Pytype - A C++ type library that is as easy to use as Python built-in types.
[edit] Incorrect word in description of basic_string overload 10)
On the following page https://en.cppreference.com/w/cpp/string/basic_string/basic_string the description of the constructor overload 10) starts with word "Implicitly". However, there is a keyword "explicit" in the declaration of that overload. Probably the word "Implicitly" should be removed or changed to "Explicitly".
Ilja Keikov e-mail: ilja.keikov@gmail.com 84.50.190.130 07:11, 26 January 2024 (PST)
- To explicitly convert an argument
t
to std::string, it must be implicitly convertible to std::string_view --Ybab321 (talk) 07:59, 26 January 2024 (PST)
[edit] Wrong version in std::vector::resize
In Template:cpp/container/resize "since=11" is used instead of "since=c++11". 2A02:586:293C:DCEC:C401:49EB:D5B7:8BB 15:13, 26 January 2024 (PST)
- ✔ Fixed.) --Space Mission (talk) 16:03, 26 January 2024 (PST)
[edit] Simplify the example in std::ios_base::width
I read the article on std::ios_base::width, and I think the example code is too complicated as a reference for people learning C++ because it uses too many C++ features that they likely don't yet know.
There is a gratuitous round-trip conversion from a chrono date literal at compile time to a std::chrono::year_month_day and then back to a string at runtime. Next, an IILE is used just to make a local const, and the IILE uses the C++23 UZ suffix and auto to make i an integer when declaring it as size_t is more straightforward. There is also gratuitous use of std::ranges::for_each and init-statements in both an if statement and range-based for loops. It uses C++23's lambdas without () which doesn't yet seem to be available in MSVC. The column width computation could arguably just be replaced with an array of numbers to avoid the doubly nested loop, but I didn't do this.
[edit] Example
#include <algorithm> #include <array> #include <iomanip> #include <iostream> #include <string> int main() { constexpr int column_size = 4; using table_t = std::array<std::string, column_size>; const auto data = std::to_array<table_t> ({ {"Language", "Author", "Birthdate", "Death date"}, // header {"C", "Dennis Ritchie", "1941-09-09", "2011-10-12"}, {"C++", "Bjarne Stroustrup", "1950-12-30", {}}, {"C#", "Anders Hejlsberg", "1960-12-02", {}}, {"Python", "Guido van Rossum", "1956-01-31", {}}, {"Javascript", "Brendan Eich", "1961-07-04", {}} }); // calculate width of each column std::array<int, column_size> cols_w; cols_w.fill(0); for (auto const& row : data) for (size_t i = 0; i != row.size(); ++i) cols_w[i] = std::max(cols_w[i], (int)row[i].size() + 2); auto print_line = [&cols_w](table_t const& tbl) { std::cout << '|'; for (size_t i = 0; i != tbl.size(); ++i) { std::cout.width(cols_w[i]); std::cout << (' ' + tbl[i]) << '|'; } std::cout << '\n'; }; auto print_break = [&cols_w] { std::cout.put('+').fill('-'); for (auto w : cols_w) { std::cout.width(w); std::cout << '-' << '+'; } std::cout.put('\n').fill(' '); }; std::cout.setf(std::ios::left, std::ios::adjustfield); print_break(); bool header = true; for (auto const& entry : data) { print_line(entry); if (header) { print_break(); header = false; } } print_break(); }
Output:
+------------+-------------------+------------+------------+ | Language | Author | Birthdate | Death date | +------------+-------------------+------------+------------+ | C | Dennis Ritchie | 1941-09-09 | 2011-10-12 | | C++ | Bjarne Stroustrup | 1950-12-30 | | | C# | Anders Hejlsberg | 1960-12-02 | | | Python | Guido van Rossum | 1956-01-31 | | | Javascript | Brendan Eich | 1961-07-04 | | +------------+-------------------+------------+------------+
2601:985:4180:D2F0:DBA:A8D2:B585:F8F3 16:12, 26 January 2024 (PST) Jack
- We're more primarily a reference site than a teaching site, but I mostly agree with the complaints. What I don't agree with is that init statements in if/for statements or lambdas without redundant parentheses being complicated or gatekeeper-esque. However, I think cramming lambdas into the main function is an unacceptable allergy to simple functions. Example is updated, thanks for the suggestion (feel free to give feedback) ✔ Done --Ybab321 (talk) 03:31, 8 February 2024 (PST)
[edit] Enhanced support in XCode 15.3 for compiler support page
See https://developer.apple.com/documentation/xcode-release-notes/xcode-15_3-release-notes
New Features The following new features have been implemented: P0645 - Text formatting (std::format) P2286R8 - Formatting ranges P1206R7 - ranges::to: A function to convert any range to a container P2520R0 - move_iterator<T*> should be a random access iterator P1328R1 - constexpr type_info::operator==() P2693R1 - Formatting thread::id P2505R5 - Monadic operations for std::expected P2711R1 - Making multi-param constructors of views explicit P2136R3 - std::invoke_r P2494R2 - Relaxing range adaptors to allow for move only types P2585R0 - Improving default container formatting P0408R7 - Efficient access to basic_stringbuf’s buffer P2474R2 - std::ranges::views::repeat P0009R18 - std::mdspan P2093R14 - Formatted output (std::ostream overload is not implemented yet)
- ✔ Added to C++20/C++23 tables.) --Space Mission (talk) 19:28, 28 January 2024 (PST)
[edit] C Operator Precedence
When parsing an expression, an operator which is listed on some row bounds its operands tighter (as if by parentheses) than any operator that is listed on a row further below it. For example, the expression *p++ is parsed as *(p++), and not as (*p)++.
[edit] Wrong return type of invoke_r
cpp/utility/functional/invoke says that invoke_r returns "The value returned by f, implicitly converted to R, if R is not void". That should be possibly cv void. 88.197.77.134 10:52, 29 January 2024 (PST)
[edit] Correction to cpp/algorithm/ranges/max_element
I noticed an error on https://en.cppreference.com/w/cpp/algorithm/ranges/max_element and wanted to correct it.
It currently says "Returns `first` if the range is empty." which should be `last`.
Ted Lyngmo (talk) 13:55, 1 February 2024 (PST)
- Yep, ✔ Fixed. Thanks. --Space Mission (talk) 14:32, 1 February 2024 (PST)
[edit] Raylib to C Libs
https://en.cppreference.com/w/c/links/libs
need to add Raylib to Graphics https://www.raylib.com/ 89.238.178.198 09:26, 3 February 2024 (PST)
- ✔ Done: RayLib's been added. --Space Mission (talk) 13:24, 3 February 2024 (PST)
[edit] Alias template partial instantiation
It is not possible to have partial instantiation of an alias template. This point is not made. I read about this on P246 of C++ Templates 2nd ed. I have also tested this and it does seem to be correct.
- There is no “partial instantiation”. If you are talking about “partial specialization”, that point is already noted in the alias template page. --Xmcgcg (talk) 17:38, 3 February 2024 (PST)
Partial instantiation does exist but not for alias templates. That point is not made. Xmcgcg you have clearly not heard of partial instantiation.
- Define partial instantiation and/or give us a link to the code you used to test this claim --Ybab321 (talk) 14:52, 4 February 2024 (PST)
Ok I will do when I have the time.
[edit] Type definitions are not allowed inside of offsetof in C23
This page c/types/offsetof mentions defining types in offsetof, which in C23 is undefined behavior.
offsetof(type, member-designator)
which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the subobject (designated by member-designator), from the beginning of any object of type type. The type and member designator shall be such that given
static type t;
then the expression &(t. member-designator) evaluates to an address constant. If the specified type defines a new type or if the specified member is a bit-field, the behavior is undefined.
Section 7.21 "Common definitions <stddef.h>" Paragraph 4 N3096
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2350.htm was the proposal which made this invalid, and it says that this was never intended to be valid.
During past discussions of the defect the committee's consensus was that despite the absence of any statement to that effect, the standard does not intend to require implementatations to accept new types in offsetof.
The sections in Notes mentioning types being defined inside of offsetof and the text saying that the type name must not have a comma outside of any parentheses should be replaced with text explaining that defining types inside of offsetof is invalid.
It may also be worth adding the same thing to va_arg, since it seems very unlikely that defining a type there is intended to be valid (it would require some recursion to even be able to evaluate an expression like va_arg(v,struct S{int a;})). Though no wording exists in the standard regarding this so it may not be worth adding.
- The edit that changed offsetof's description to what it is now references N3148 DE-137 which relaxed the restriction on offsetof. The current draft seems to be outdated. 2A02:586:293C:DCEC:D93D:8861:85FD:85B6 05:18, 6 February 2024 (PST)
[edit] Update C23 working draft to N3149
Please change N3096 on c/23 to N3149. --Aaron Liu (talk) 14:17, 6 February 2024 (PST)
The title of the section was changed to make it unique, by --Space Mission (talk) 16:32, 7 February 2024 (PST)
- ✔ Done. See C23. --Space Mission (talk) 16:32, 7 February 2024 (PST)
[edit] Typo in operator""ns example output
In example: 10000ns = 1000 nanoseconds Should be: 1000ns = 1000 nanoseconds
In std::literals::chrono_literals::operator""ns [7] In example: 10000ns = 1000 nanoseconds Should be: 1000ns = 1000 nanoseconds
- Two sections were merged and the title was extended, by --Space Mission (talk) 15:38, 7 February 2024 (PST)
- ✔ Fixed: check it here. Thanks. --Space Mission (talk) 15:38, 7 February 2024 (PST)
[edit] std::pmr::monotonic_buffer_resource example has UB
In lambda `pmr_alloc_and_buf` there is a `std::array` being used as a storage for allocating elements inside it. However, standard says, that C++-style objects can't provide storage -- it's the reason why `std::aligned_storage_t` is deprecated in C++23. Changing `std::array` to C-style array would work fine here with respect to the standard.
- Hm, but
std::array
as an aggregate is composed of a C-style array, so does that not make it OK? --Ybab321 (talk) 03:02, 7 February 2024 (PST)
[edit] better std::filesystem::space example
Regarding std::filesystem::space [8] , it would be very helpful for coders to have an example of how to calculate the disk use%.
I spent a long time trying stuff, until I came across this https://stackoverflow.com/a/74569692
In hindsight it is obvious, but this is probably what many people will want to do, so please can it be included, to cut down on unnecessary the googling time. PS: Hope I can register an account here soon . Thanks
#include <cstdint> #include <filesystem> #include <iostream> double disk_usage(const std::filesystem::space_info &si) { const double used = si.capacity - si.free; const double usage = used/(used + si.available); // https://stackoverflow.com/a/74569692 return usage; } void print_space_info(auto const& dirs, int width = 15) { (std::cout << std::left).imbue(std::locale("en_US.UTF-8")); for (const auto s : {"Use%", "Capacity", "Free", "Available", "Dir"}) std::cout << "│ " << std::setw(width) << s << ' '; for (std::cout << '\n'; auto const& dir : dirs) { std::error_code ec; const std::filesystem::space_info si = std::filesystem::space(dir, ec); std::cout << "│ " << std::setw(width) << disk_usage(si)*100 << ' '; for (auto x : {si.capacity, si.free, si.available}) std::cout << "│ " << std::setw(width) << static_cast<std::intmax_t>(x) << ' '; std::cout << "│ " << dir << '\n'; } } int main() { const auto dirs = {"/dev/null", "/tmp", "/home", "/proc", "/null"}; print_space_info(dirs); }
- Would be happy to add, but shouldn't the calculation be 1 - double(si.free) / si.capacity? Seems like either
free
oravailable
should be chosen and used consistently based on whether you care about privileged or non-privileged space --Ybab321 (talk) 03:25, 9 February 2024 (PST)
- ✔ Done. Added the disk_usage_percent() function with consistent usage of std::filesystem::space_info::free/
available
, plus a few minor extensions.) --Space Mission (talk) 19:33, 9 February 2024 (PST)
- ✔ Done. Added the disk_usage_percent() function with consistent usage of std::filesystem::space_info::free/
[edit] Incorrect possible implementation of std::invoke
LWG3655 needs to be applied to the possible implementation in cpp/utility/functional/invoke. 2A02:1388:181:A912:0:0:58E1:1110 00:32, 8 February 2024 (PST)
- Updated (and also fixed I think), thanks ✔ Done --Ybab321 (talk) 02:57, 8 February 2024 (PST)
- It is fixed now, thanks. However,
I think(I tested it and it fails for unions 04:40, 9 February 2024 (PST)) cpp/types/result_of#Possible implementation has a similar problem since it also uses is_base_of. There may be even more pages with the same problem. 2A02:1388:181:A912:0:0:58E1:1110 06:49, 8 February 2024 (PST)
- It is fixed now, thanks. However,
[edit] std::expected constructor signature
In std::expected<T,E>::expected, overload (11) I'm 99% sure that this overload should not be a template.
[edit] std::expected<T,E>::swap error
In the explanation of the method, the first case described as:
Otherwise, equivalent to using std::swap; swap(*this, other);.
Should actually say:
Otherwise, equivalent to using std::swap; swap(**this, *other);.
[edit] map.emplace example doesn't show what happens if the key is duplicated
I think the example should end with an additional call with an existing key. The example output shouldn't change if my understanding is correct (that the original value remains).
69.250.84.4 05:46, 9 February 2024 (PST)
- Got there eventually ^^;. Added ✔ Done --Ybab321 (talk) 14:46, 18 February 2024 (PST)
- Thanks! 💖 (Same reader I guess it decided to go IPv6 this time.) 2601:154:C300:154:14C1:474E:1DBF:8C81 04:32, 27 February 2024 (PST)
[edit] std::unordered_map::operator[] complexity
188.187.79.224 11:27, 9 February 2024 (PST)
https://en.cppreference.com/w/cpp/container/unordered_map/operator_at#Complexity
Says: "Average case: constant, worst case: linear in size."
This is wrong, because in worst case operator[] could lead to std::unordered_map::rehash which is quadratic.
In case of questions, write to Doctor.Shadow.Q@gmail.com
188.187.79.224 11:27, 9 February 2024 (PST)
- ✔ Updated: see complexity. Thanks.) --Space Mission (talk) 21:57, 12 February 2024 (PST)
- But it's not true.
std::unordered_map::operator[]
=std::unordered_map::try_emplace
=std::unordered_map::emplace
, which has O(n) complexity --Ybab321 (talk) 03:05, 13 February 2024 (PST)
- But it's not true.
- O(n) worst-case insertion is correct (see this page). The key is that the automatic rehashing of unordered associative containers can definitely be done in O(n) time. Either it has different implementation from
rehash()
, or the worst case ofrehash()
never applies to it. --Xmcgcg (talk) 08:21, 13 February 2024 (PST)
- O(n) worst-case insertion is correct (see this page). The key is that the automatic rehashing of unordered associative containers can definitely be done in O(n) time. Either it has different implementation from
[edit] Incorrect declaration, description or exception number marks
Due to the lockdown I cannot edit these myself, but there are some pages that have a mismatch between the number marks of the declaration, description or exception sections.
Declarations are missing overload number marks used in description: https://en.cppreference.com/w/cpp/chrono/time_zone/to_sys
Second overload is marked as (3) instead of (2): https://en.cppreference.com/w/cpp/atomic/atomic_exchange
'-=' overloads must be marked as (2) instead of (1): https://en.cppreference.com/w/cpp/atomic/atomic_ref/operator_arith2
Exception section refers to (3) overload, but third overload is marked (2): https://en.cppreference.com/w/cpp/experimental/fs/is_block_file https://en.cppreference.com/w/cpp/experimental/fs/is_character_file https://en.cppreference.com/w/cpp/experimental/fs/is_symlink https://en.cppreference.com/w/cpp/experimental/fs/is_socket
Third overload is marked as (2) instead of (3): https://en.cppreference.com/w/cpp/experimental/fs/path/operator%3D
In the description "4)" label should be "2)": https://en.cppreference.com/w/cpp/experimental/special_functions/assoc_legendre https://en.cppreference.com/w/cpp/experimental/special_functions/assoc_laguerre
- ✔ Done. All items in the above are fixed and patched, thanks you. :D --Space Mission (talk) 06:06, 10 February 2024 (PST)
[edit] C round() function page bug
"The double
version of round behaves as if implemented as follows:"
#include <math.h> double round(double x) { return signbit(x) ? ceil(x - 0.5) : floor(x + 0.5); }
This implementation is incomplete and wrong! You need to the rounding mode to FE_TOWARDZERO
to get the correct result of (x ± 0.5). Or else a value of x = (0.5 - DBL_EPSILON / 2)
or x = (0.5 - DBL_EPSILON / 4)
would give you the wrong results. The C++ page of std::round
has the correct implementation.
--2001:B400:E135:3046:3423:72F7:6AAF:938E 04:18, 10 February 2024 (PST)
- ✔ Done. The C and C++ pages were updated. Thanks.) --Space Mission (talk) 22:20, 11 February 2024 (PST)
[edit] Confusion about "special" member functions and constructors
From cpp/language/constructor:
> Constructor is a special non-static member function of a class that is used to initialize objects of its class type.
The word "special" can lead to confusion. Not all constructors are *special member functions*.
I propose removing the word "special" or replacing it with "kind of"
68.50.220.16 11:45, 10 February 2024 (PST) strager
- Fixed. Now “special” appertains to declarator syntax. ✔ Done --Xmcgcg (talk) 05:40, 12 February 2024 (PST)
[edit] Execution library
- Sender: A description of asynchronous work to be sent for execution. Produces an operation state (below).
- Senders asynchronously “send” their results to listeners called “receivers” (below).
- Senders can be composed into task graphs using generic algorithms.
- Sender factories and adaptors are generic algorithms that capture common async patterns in objects satisfying the sender concept.
- Receiver: A generalized callback that consumes or “receives” the asynchronous results produced by a sender.
- Receivers have three different “channels” through which a sender may propagate results: success, failure, and canceled, so-named “value”, “error”, and “stopped”.
- Receivers provide an extensible execution environment: a set of key/value pairs that the consumer can use to parameterize the asynchronous operation.
- Operation State: An object that contains the state needed by the asynchronous operation.
- A sender and receiver are connected when they are passed to the
std::execution::connect
customization point. - The result of connecting a sender and a receiver is an operation state.
- Work is not enqueued for execution until “
start
” is called on an operation state. - Once started, the operation state’s lifetime cannot end before the async operation is complete, and its address must be stable.
- A sender and receiver are connected when they are passed to the
- Scheduler: A lightweight handle to an execution context.
- An execution context is a source of asynchronous execution such as a thread pool or a GPU stream.
- A scheduler is a factory for a sender that completes its receiver from a thread of execution owned by the execution context.
Ericniebler (talk) 19:28, 11 February 2024 (PST)
- ✔ Copied to Execution Library page.) --Space Mission (talk) 22:09, 11 February 2024 (PST)
[edit] Segfault in the example of the page std::time_get<CharT,InputIt>::get, std::time_get<CharT,InputIt>::do_get
In the page std::time_get<CharT,InputIt>::get, std::time_get<CharT,InputIt>::do_get, there is an error in the code example:
ss.imbue(std::locale("de_DE.utf8")); auto& f = std::use_facet<std::time_get<char>>(std::locale("de_DE.utf8"));
It should be:
auto locale = std::locale("de_DE.utf8"); ss.imbue(locale); auto& f = std::use_facet<std::time_get<char>>(std::locale("de_DE.utf8"));
Indeed, the facet `f` becomes invalid as far as the call to the function ended.
2A01:E0A:BA5:C8D0:CB4E:AC46:709F:2E 01:59, 12 February 2024 (PST)
- Locales are reference counted, the code should be fine as is. What compiler are you using? --Ybab321 (talk) 04:51, 12 February 2024 (PST)
- The problem is actually caused by std::use_facet. Two std::locale("de_DE.utf8") objects might not refer to the same locale object, therefore f becomes a dangling reference. The previous version of the example does not produce any output for GCC. I changed the argument to ss.getloc() and everything works fine now. ✔ Done --Xmcgcg (talk) 05:40, 12 February 2024 (PST)
[edit] Broken link in example
On the following page: https://en.cppreference.com/w/cpp/experimental/shuffle
The link in the example for the "std::experimental::shuffle" call is broken and links to a non-existent page: http://en.cppreference.com/w/cpp/experimental/shufflea
I am not sure why that is - the links the Example/code blocks look to be automatically generated?
- This is indeed a typo in this auto html links database. You may find the wrong word by searching for
- shufflea. It certainly should be just
- shuffle. To be fixed.) --Space Mission (talk) 00:18, 14 February 2024 (PST)
[edit] CWG2518 - clang 17.0.1 supports static_assert(false)
I can't change the table because I'm too new a user :(
https://clang.godbolt.org/z/WKPjnGEMs
- ✔ Done: here. Thanks. --Space Mission (talk) 20:21, 14 February 2024 (PST)
[edit] Fix spelling error
Original content removed. It was the content of std::format.
- You can provide the exact location of the error. We will handle it. --Xmcgcg (talk) 06:48, 16 February 2024 (PST)
[edit] Typo on strfromf
On https://en.cppreference.com/w/c/string/byte/strfromf
The line: int strfroml( char *restrict s, size_t n, const char *restrict format, long double fp );
should be: int strfromld( char *restrict s, size_t n, const char *restrict format, long double fp ); 50.168.87.114 14:57, 16 February 2024 (PST)
- The standard says
strfroml
is correct. Was that changed in the password protected draft? If yes, please provide a source showing the change. 2A02:586:293C:DC56:B9C4:EE4A:86D5:16D0 16:08, 16 February 2024 (PST)- Can someone correct the page title of c/string/byte/strfromf? 2A02:586:293C:DC56:2C46:9513:3BA0:9F84 04:29, 17 February 2024 (PST)
[edit] faulty example
I do not get the examples given. Both examples do in fact insert a separator when running the code.
[edit] Bit-field of width zero in a union
c/language/bit_field says that "The special unnamed bit-field of width zero breaks up padding: it specifies that the next bit-field begins at the beginning of the next allocation unit". This is only true if the bit-field is a structure member but not a union member. The C standard says (emphasis mine)As a special case, a bit-field structure member with a width of 0 indicates that no further bit-field is to be packed into the unit in which the previous bit-field, if any, was placed.Interestingly, this is not a problem in C++ because that standard only says that
As a special case, an unnamed bit-field with a width of zero specifies alignment of the next bit-field at an allocation unit boundary.which doesn't cause problems when applied to unions. 2A02:586:293C:DC56:1576:6BEE:E002:DCA 17:45, 18 February 2024 (PST)
[edit] Apply N2829 to c/error/assert
That is the same change as P2264R7 for cpp/error/assert but for C. 2A02:586:293C:DC56:1576:6BEE:E002:DCA 18:16, 18 February 2024 (PST)
[edit] Syntax highlighting missing keywords
It's minor, but all new C++ 20 keywords are not syntax highlighted on the site: char8_t, concept, consteval, constinit, co_await, co_return, co_yield, requires
There are also some C++11 keywords that are not highlighted (incomplete list): static_assert, thread_local, nullptr
Maybe there is a reason not to or there is a technical limitation, but I think all the reserved keywords in the top table should be highlighted as such. https://en.cppreference.com/w/cpp/keyword
Kkitanov (talk) 00:42, 19 February 2024 (PST)
[edit] Small fix for std::expected
In description of the converting copy/move constructors:
> If T is not (possibly cv-qualified bool)
should be replaced with:
> If T is not (possibly cv-qualified) bool
[edit] Bug in filesystem space example
The example here
https://en.cppreference.com/w/cpp/filesystem/space
is buggy.
Please use this code instead:
https://wandbox.org/permlink/SEw1elbZYfSAxeJ8
Reason:
reserved ^ ----- ^ ^ v |___| | | ^ | | | free | available | | | | | v |___| v | capacity | | ^ | | | | used | | | | | ----- v v
Assume these numbers
capacity = 100 free = 55 available = 50 used = capacity - free = 45 reserved = free - available = 5
Correct) (https://wandbox.org/permlink/SEw1elbZYfSAxeJ8)
privileged = false [disk-usage-for-normaler-user] ================== usage = used / (used+available) = (capacity - free) / (capacity - free + available) = 45 / 95 privileged = true [disk-usage-for-privileged-user] ================== usage = used / (used+available+reserved) = (capacity - free) / (capacity) = 45 / 100
Wrong) (current implementation)
privileged = false [disk-usage-for-normaler-user] ================== usage = (capacity - available) / capacity = 50 / 100 privileged = true [disk-usage-for-privileged-user] ================== usage = (capacity - free) / capacity = 45 / 100
Thanks.
It is still wrong. It is not like my code, which does the right thing. Why do I say my code (linked above) does the right thing? Because I ensured it works exactly like the Linux df command - and that does the right thing. Please go through my code and understand how it (still) differs from the current version here. Then please correct it. Thanks
- Ok, I looked at yours in detail now and you refactored (or may I say: overcomplicated) the code, but the result is in fact correct. But (as implied) I really do find it quite complex, to be honest (that's the reason I originally thought it was actually different).
- Just consider the following, which is your current implementation
privileged = false [disk-usage-for-normaler-user] ================== usage = ((si.capacity-(si.free - si.available) - (si.free-(si.free - si.available))) / (si.capacity-(si.free - si.available)) ------------------------------------ ---------------------------------- ------------------------------------ capacity unused_space capacity = ((si.capacity-si.free)) / (si.capacity-(si.free - si.available)) = 50 / 100
- That (ultra-long) line on top is the calculation expansion.
- My code is much simpler (and easier to understand -- at least for me):
const std::uintmax_t used{si.capacity - si.free}; const std::uintmax_t total_usable{privileged ? si.capacity : (used + si.available)}; if (constexpr auto X{static_cast<std::uintmax_t>(-1)}; total_usable == 0 || si.capacity == X) { return X; // signal error } return 100 * used / total_usable;
- Just look at that conditional operator (ternary conditional). Is that not much simpler???! Also the comment in my version can help users: https://wandbox.org/permlink/SEw1elbZYfSAxeJ8
- Could we not change the code to be similar to that??? Thanks!!
- (The error handling is also different: istead of returning blank 100, I return X. But about that I don't care too much.)
The code is fine as is, cramming stuff into one line doesn't make the code simpler, it just takes away the possibility of adding names to identify the calculations. Try to identify logical or semantic issues, or general engineering improvements in your code reviews; pointing out mere differences between two pieces of code isn't productive, nor persuasive. --Ybab321 (talk) 07:40, 22 February 2024 (PST)
- Your use of capacity and si.capacity is confusing. So your point of "adding names to identify" is mute. My name is total_usable, which is better. Mine even has a description with a comment. And my version has higher performance. Think about it.
[edit] C++23: flat_map::emplace has incorrect complexity
For cpp/container/flat_map/emplace, complexity is dictated as N + M log M, where N is the original flat_map size, and M is the number of inserted elements.
Some pages (e.g. flat_map::emplace) appear to have been at least partially copied from map instead.
- Fixed flat map emplace (though it could be expressed more precisely by writing out the implementation like the standard does, that's on the todo list). ✔ Done --Ybab321 (talk) 08:00, 22 February 2024 (PST)
[edit] Confusion in std::list<T,Allocator>::size description
Hi,
In the description of "std::list<T,Allocator>::size" it is stated that:
"Returns the number of elements in the container, i.e. std::distance(begin(), end())."
This is confusing, since starting from C++11, the size() method has constant complexity while the std::distance has linear complexity for bidirectional iterators. So, I suggest removing this confusing statement ('i.e. std::distance(begin(), end())') from the description.
Thanks, Misak Shoyan
- The complexity is stated in the complexity section. I see no possible source of confusion over the time complexity of that function --Ybab321 (talk) 07:45, 22 February 2024 (PST)
[edit] Missing overload
On page std::ostream_iterator<T,CharT,Traits>::operator= there is a missing overload:
ostream_iterator& operator=(const ostream_iterator&) = default;
See file stream_iterator.h
line 236.
--2A02:85F:FC70:F0CB:8952:BAE1:2759:C6C9 09:54, 22 February 2024 (PST)
[edit] Not compilable code for example which goes into Comiler Explorer in std::ranges::to
https://godbolt.org/z/os4YKEEbv - working example 178.148.7.85 23:22, 22 February 2024 (PST) Sakhil
- libc++ has
<print>
now, that's great (also thanks ADL for making us aware of this :D). Updated the link, thanks. ✔ Done --Ybab321 (talk) 03:04, 23 February 2024 (PST)
[edit] Missing semicolumn at the end of the example code
Semincolumn is missing at the end of the sample code below:
... // array of 5 pointers to functions returning pointers to arrays of 3 ints int (*(*callbacks[5])(void))[3]; ...
- Thanks, semicolon inserted (what am I, javascript?) ✔ Done --Ybab321 (talk) 03:04, 23 February 2024 (PST)
[edit] Compiler support for C++23 - Some Explanation of the numbers
Regarding:
[ https://en.cppreference.com/w/cpp/compiler_support/23] and those like it.
Might I suggest that somewhere on this page there is some explanation of the version numbers and how to find them. I have just spent some time trying to find if my Visual Studio 2022 compiler had some feature, to find that none of the obvious "version numbers" displayed by the visual interface are the relevant one, and that the only way to determine this is to look up a table such as
[ https://en.wikipedia.org/wiki/Microsoft_Visual_C%2B%2B#Internal_version_numbering]
or reading the article by Raymond Chen here
[ https://devblogs.microsoft.com/oldnewthing/20221219-00/?p=107601]
or to compile something like:
std::cout << "_MSC_FULL_VER:\n" << _MSC_FULL_VER <<std::endl;
Practically - maybe make the column heading a link to the Wikipedia table, or a page where you explain what the reference means. I would happily contribute such an intermediate page.
Paul McGinnie (not a user with an account) 81.174.231.177 03:36, 26 February 2024 (PST)
- If you mouse-hover the version number cell it gives you the useful version number. Not that I'm against your suggestions --Ybab321 (talk) 09:34, 26 February 2024 (PST)
[edit] Return value description in Template:cpp/container/try_emplace_assoc
Hi,
First of all, thanks for this wonderful website, I'm using it almost every day.
I think that in the return value section, the description of false boolean value should rather talk about no action happening instead of assignment being done. Feels a bit like a copy-pasta from insert_or_assign. :) I don't have an account here, so I can't edit the page myself.
Cheers!
45.135.60.1 12:24, 26 February 2024 (PST) Krzesimir Nowak
[edit] Incorrect return type for C++98's std::deque::insert
Hi,
The declaration for std::deque::insert( const_iterator pos, size_type count, const T& value ) is incorrect for C++98. According to https://cplusplus.com/reference/deque/deque/insert/ and the STL's implementation (https://github.com/gcc-mirror/gcc/blob/master/libstdc%2B%2B-v3/include/bits/stl_deque.h), this method should return void, and not an iterator.
Since this page is protected, I can't edit it, hopefully someone with the rights can do that instead.
2A02:8440:C207:342D:6972:67C3:F744:F283 17:48, 26 February 2024 (PST)
- the change is mentioned on the page under cpp/container/deque/insert#Defect_reports. It's true that gnu stdlib doesn't implement it as a retroactive defect report, while microsoft and llvm all return iterators. --Cubbi (talk) 19:50, 26 February 2024 (PST)
[edit] std::expected::emplace initializer_list argument not a reference
According to P0323r11 and some implementations, it looks like the type of the initializer_list argument is just std::initializer_list<U> and not std::initializer_list<U>&. This also matches the other constructors, etc.
Brad Spencer (talk) 07:04, 27 February 2024 (PST)
- ✔ Patched. Thanks. --Space Mission (talk) 08:28, 27 February 2024 (PST)
[edit] in 'Compiler support for C++23' deducing this marked as full support for gcc and clang, but is only partial
both clang and gcc are missing P2797R0/CWG2692 (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2797r0.html)
sources:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102609
https://clang.llvm.org/cxx_status.html#cxx23
[edit] Invalid examples of std::signal
I have found several pages that contain incorrect usages of std::signal.
cpp/utility/program/signal: The example does not make the signal handler 'extern "C"' even though the declaration at the top of the page indicates that it expects this.
cpp/utility/program/raise: The example does not make the signal handler 'extern "C"', and prints inside of the signal handler which isn't signal safe.
cpp/utility/program/abort: Same as above.
c/program/raise: The example prints inside of the signal handler which isn't signal safe.
c/program/SIG_ERR: Same as above.
- as discussed in c/program/signal and cpp/utility/program/signal, signal safety only applies to async signals, which aren't used in those examples. C++ linkage support is implementation-defined but I suppose C linkage would indeed be prudent for use in examples. --Cubbi (talk) 10:20, 28 February 2024 (PST)
- on second thought, it looks like the changes in http://wg21.link/p0270 technically eliminated sync signal wording with a note "It may make sense to eventually relax these restrictions invoked through an explicit synchronous raise() call. It's unclear that this is important enough to bother.".. while I doubt any programmers (and therefore compiler vendors) expect existing sync signals to suddenly turn into free-for-all UB, maybe it is worth the effort to show async-signal-safe examples even if invoked synchronously --Cubbi (talk) 10:43, 28 February 2024 (PST)
[edit] std::map<Key,T,Compare,Allocator>::try_emplace -- ignored vs assignment map
The body return value section found on map::try_emplace [[9]] says it returns "false if the assignment took place". However, other parts of the page mention no such assignment. Rather, it appears to ignore the input in the even a false statement is returned.
204.113.92.35 11:51, 29 February 2024 (PST) Clint Chelak, cachelak@gmail.com
[edit] final specifier
The final specifier cannot be placed on a class declaration such as class A final; This is not particularly clear on the page for final.
Ok Thanks. The example struct final final; is clearly a declaration and needs removing or something.
- Why would it need removing? It's not a class declaration, as the explanatory text points out --Ybab321 (talk) 08:12, 14 March 2024 (PDT)
[edit] float.h: MAX_EXP: naming / definition questionable,
FLT_MAX_EXP DBL_MAX_EXP LDBL_MAX_EXP
maximum positive integer such that FLT_RADIX raised by power one less than that integer is a representable finite float, double and long double respectively (macro constant)
That description matches with the value produced for e.g. DBL_MAX_EXP, but why that cumbersome way, and misleading name? The value returned isn't 'MAX_EXP' but 'MIN_TOO_BIG_EXP'.
176.4.134.52 18:45, 2 March 2024 (PST)
- C just isn't a language that espouses good identifier naming, your complaint is completely valid --Ybab321 (talk) 09:35, 7 March 2024 (PST)
[edit] Add "some" to examples intro in cpp/language/ub
In the "Explanation" section, under "undefined behavior", change "Examples" to "Some examples". 2600:8800:1180:25:F5FB:C6B8:87F2:F13C 11:29, 3 March 2024 (PST)
- ✔ Done.) --Space Mission (talk) 12:49, 3 March 2024 (PST)
[edit] What are the "A program is well-formed" tags about in cpp/language/ub?
In the "Explanation" section there are awkward sentences like "A program is well-formed" tacked on to the end of some of the paragraphs. Should it be "Such a program..." instead? And are they necessary to disambiguate some question, or is it just obvious whether such a program is well- or ill-formed? 2600:8800:1180:25:F5FB:C6B8:87F2:F13C 11:29, 3 March 2024 (PST)
- Those "tags" are unnecessary/not entirely accurate and have been removed.) ✔ Done. --Space Mission (talk) 14:11, 3 March 2024 (PST)
[edit] Typo in explanation
line: -c + d; // equivalent to (-c) + d, NOT -(a + b)
should be: -c + d; // equivalent to (-c) + d, NOT -(c + d)
80.188.171.120 04:35, 6 March 2024 (PST) Miroslav Rýzek
[edit] std::mutex example could use structured binding
Hello. New user here. I'd like to make a small change to the example code for std::mutex. It could make use of structured binding in its range-based for loop, e.g.
for (const auto& [url, page] : g_pages) std::cout << url << " => " << page << '\n';
PaulCpp (talk) 12:13, 6 March 2024 (PST)
[edit] Two libraries
It would be good to add https://github.com/jeremy-rifkin/cpptrace and https://github.com/jeremy-rifkin/libassert to https://en.cppreference.com/w/cpp/links/libs. They are diagnostic-related libraries but probably fit best under logging. I would add them, however, apparently I cannot as my account is considered new.
[edit] C23 feature support by compiler
https://en.cppreference.com/w/c/compiler_support/23
typeof() support listed for MSVC is incorrect.
Support does exist as of MSVC/Visual Studio 2022 17.9
https://learn.microsoft.com/en-us/cpp/c-language/typeof-c?view=msvc-170
Version supporting was released February 13, 2024
2001:470:8B06:100:B43F:65F6:9FE7:7B64 16:51, 7 March 2024 (PST) gdwnldsKSC
[edit] Libraries: PcapPlusPlus missing license & configuration
Hey,
I noticed that PcapPlusPlus is missing license & configuration info on the page: https://en.cppreference.com/w/c/links/libs
Missing data is:
- license: Unilicense
- configuration: CMake (since v22.11)
Reference: https://github.com/seladb/PcapPlusPlus
Thanks!
178.235.17.242 05:42, 8 March 2024 (PST) WojtekMs
- ✔ Added.) --Space Mission (talk) 16:38, 8 March 2024 (PST)
- The link to PcapPlusPlus can be found here: https://en.cppreference.com/w/cpp/links/libs#Communication --Space Mission (talk) 16:45, 8 March 2024 (PST)
[edit] CTRE
Looking through this list, I was surprised to not see CTRE. The compile time regular expression library is praised often on conferences and podcasts. Unlike std::regex, this parses the regex at compile time and makes a dedicated parser for the regex you want to use. I believe this belongs in the group Text.Parsing. URL: https://github.com/hanickadot/compile-time-regular-expressions Type: header only License: Apache 2 Description: Fast compile-time regular expressions with support for matching/searching/capturing during compile-time or runtime.
- Not having CTRE was unwise indeed.) ✔ Added. --Space Mission (talk) 03:32, 10 March 2024 (PDT)
[edit] Update description of example for transform
The example for transform: https://en.cppreference.com/w/cpp/algorithm/transform contains an extra step that is not described in the preceding text, which says, "The following code uses transform to convert a string in place to uppercase using the std::toupper function and then transforms each char to its ordinal value:..." In fact, the example also has a step where each ordinal value is added to itself, apparently to demonstrate that transform can apply binary operators. It would be good for the explanatory text to be updated.
Alex Szatmary, http://sites.google.com/site/alexszatmary/ 174.178.62.175 14:02, 10 March 2024 (PDT)
- Desynchronised documentation is such a pain. Fixed, thanks ✔ Done --Ybab321 (talk) 06:39, 29 March 2024 (PDT)
[edit] Static data members declared inline
One of the reasons for the introduction of the inline word is that a non-literal type can be initialised in a header file as so:
struct Monster { Monster(long num) { std::cout << "Starting monster " << num << std::endl; } };
struct Level { inline static Monster fav = Monster{9}; // OK since C++17 };
The page only gives an example with an int.
[edit] Modification of the example in c/io/fputwc to be compatible with MSVC
In the example of the page c/io/fputwc, there is the following code:
if (fputwc(L'🍌', stdout) == WEOF)
L'🍌' is a wchar_t which is implementation defined, and, on MSVC for instance, wchar_t is 2 bytes long. This is an issue because the banana emoji cannot be represented in 2 bytes or less. I would suggest to use the Timer Clock emoji (⏲), for instance, which can be represented in 2 bytes. This would make this example compliant on all platforms.
2A01:E0A:BA5:C8D0:903E:5584:51F6:1C47 05:41, 15 March 2024 (PDT)
[edit] Modification of the example in c/language/string_literal
In the example of the page c/io/fputwc, there is the following code:
wchar_t s5[] = L"a猫🍌";
wchar_t is implementation defined, and, on MSVC for instance, wchar_t is 2 bytes long. This is an issue because the banana emoji cannot be represented in 2 bytes or less. I would suggest to use the Timer Clock emoji (⏲), for instance, which can be represented in 2 bytes. This would make this example compliant on all platforms.
2A01:E0A:BA5:C8D0:903E:5584:51F6:1C47 06:10, 15 March 2024 (PDT)
- quite a few cppreference examples showcase features that aren't supported by some of the big 3 implementations (or in a few cases even features not supported by any of the big 3). Trimming examples to what works in that intersection would both lose examples that demonstrate practical (just not universal) use, and the examples that shame vendors into improvement (this worked in the past - though I know MS will never do this one). Besides, U+23F2 wouldn't show anything that U+732B doesn't already. --Cubbi (talk) 10:12, 15 March 2024 (PDT)
[edit] Misprints in cpp/atomic/atomic
std::atomic<U*> is stated to be defined in <memory>. This is a misprint. This remark is related to std::atomic<std::shared_ptr<U>> and std::atomic<std::weak_ptr<U>>. There is a similar misprint with <stdatomic.h>. This header should be moved from std::atomic<std::weak_ptr<U>> to #define _Atomic(T).
std::atomic<U*> is stated to be defined in <memory>.
- This is not true. According to [atomics.syn], std::atomic<U*> is defined in <memory>. --Xmcgcg (talk) 19:34, 17 March 2024 (PDT)
- According to the mentioned page, std::atomic<U*> is defined in <atomic>, not in <memory>. The partial specializations for smart pointers are declared in <memory>. See [util.smartptr.atomic.general] Olegrog (talk) 07:16, 18 March 2024 (PDT)
- Oops. What I wanted to say is “According to [atomics.syn], std::atomic<U*> is defined in <atomic>.” The std::atomic page does correctly state the headers. --Xmcgcg (talk) 18:30, 18 March 2024 (PDT)
[edit] Suggest changes in cpp/algorithm/upper_bound explanation
As explained, if the order is determined by comp: the function returns the first iterator iter in [first, last) where bool(comp(value, *iter)) is false, or last if no such iter exists.
But actually it keeps incrementing first iterator while comp(value, *iter) == false. When count == 0 the incremented iterator is returned. And comp(value, *iter) for this iterator will return True. So in fact the std::upper_bound returns the first iterator next to the last iterator where bool(comp(value, *iter)) is false or the first iterator where bool(comp(value, *iter)) is true.
The working example is here: binary-search-comparator-checker
For the comparison, the explanation on the cpp/algorithm/lower_bound page is correct.
Viktor Kustov kustovvictor@gmail.com
--178.66.130.191 19:11, 17 March 2024 (PDT)
[edit] (T)_MAX_10_EXP descriptions wrong,
In the definitions for numeric limits I find:
"FLT_MAX_10_EXP DBL_MAX_10_EXP LDBL_MAX_10_EXP
maximum positive integer such that 10 raised by power one less than that integer is a representable finite float, double and long double respectively"
my system with a relatively recent gcc produces: FLT_MAX_10_EXP: 38, where ~3.4E+38 is representable, DBL_MAX_10_EXP: 308, where ~1.7E+308 is representable, LDBL_MAX_10_EXP: 4932, where ~1.8E+4932l is representable,
thus usable max exponent and value provided match without the 'one less than that integer'.
Think the questionable description is meaningless copied from '(T)_MAX_EXP' for base 2.
Either the macros should provide 39 / 309 / 4933 - bad, or the description changed to '... by power one less than that integer is a representable ...'
176.4.134.69 02:47, 25 March 2024 (PDT)
- ✔ Done yes, this is C's 5.2.4.2.2/11, c/types/limits had it wrong, likely copy-paste from other points, cpp/types/climits had it right --Cubbi (talk) 07:30, 25 March 2024 (PDT)
[edit] example for cpp/algorithm/ranges/find
I want to add better example for std::find(range, value, proj) like:
[edit] Example
#include <algorithm> #include <iostream> #include <iterator> #include <vector> int main() { struct table_row { std::uint32_t uid; std::string name; std::string info; }; std::vector<table_row> table = { { 1, "leo", "developer" }, { 2, "dima", "developer" }, { 3, "igor", "developer" } }; // how to "project" internal value auto it = std::ranges::find(table, "igor", &table_row::name); cout << "uid: " << it->uid << '\n' << "name: " << it->name << '\n' << "info: " << it->info << '\n'; namespace ranges = std::ranges; const int n1 = 3; const int n2 = 5; const auto v = {4, 1, 3, 2}; if (ranges::find(v, n1) != v.end()) std::cout << "v contains: " << n1 << '\n'; else std::cout << "v does not contain: " << n1 << '\n'; if (ranges::find(v.begin(), v.end(), n2) != v.end()) std::cout << "v contains: " << n2 << '\n'; else std::cout << "v does not contain: " << n2 << '\n'; auto is_even = [](int x) { return x % 2 == 0; }; if (auto result = ranges::find_if(v.begin(), v.end(), is_even); result != v.end()) std::cout << "First even element in v: " << *result << '\n'; else std::cout << "No even elements in v\n"; if (auto result = ranges::find_if_not(v, is_even); result != v.end()) std::cout << "First odd element in v: " << *result << '\n'; else std::cout << "No odd elements in v\n"; auto divides_13 = [](int x) { return x % 13 == 0; }; if (auto result = ranges::find_if(v, divides_13); result != v.end()) std::cout << "First element divisible by 13 in v: " << *result << '\n'; else std::cout << "No elements in v are divisible by 13\n"; if (auto result = ranges::find_if_not(v.begin(), v.end(), divides_13); result != v.end()) std::cout << "First element indivisible by 13 in v: " << *result << '\n'; else std::cout << "All elements in v are divisible by 13\n"; }
Output:
v contains: 3 v does not contain: 5 First even element in v: 4 First odd element in v: 1 No elements in v are divisible by 13 First element indivisible by 13 in v: 4
[edit] Suggested change for `std::format` example
I don't believe that initializing the iterator variable `i` with braces is a good practice in the std::format example, specifically because it may cause ambiguity with the format string's own brace formatting and does not show the actual value of `i` in the code. Given that I have not seen empty brace initialization (even specifically for a variable with a zero value) anywhere else on this site, I feel it should be a simple `int i = 0;` in order to be consistent.
-- Greg W.
69.18.24.155 07:22, 26 March 2024 (PDT)
- The braces used to initialise a variable don't cause ambiguity with the braces in an unrelated string literal.
T{}
is common form for value initialisation outside of cppreference, I see no reason to avoid using it, we do lots of stuff with different styles here, and that can be argued as good for exposure to those styles. I admit though, I don't care whether we use value init or copy init to 0 --Ybab321 (talk) 08:08, 26 March 2024 (PDT)
[edit] offsetof typo
On both the C and C++ documentation pages for offsetof, there is a typo in the word "containg" which should be "containing". - Bryce 64.124.34.109 13:16, 26 March 2024 (PDT)
[edit] update malloc page according recent C23 changes
> Return value On success, returns the pointer to the beginning of newly allocated memory. To avoid a memory leak, the returned pointer must be deallocated with free() or realloc().
Since C23, realloc cannot be used to free() memory -- zero size for realloc() is undefined behaviour
https://en.cppreference.com/w/c/memory/realloc
- Use of non-zero sized
realloc
on the returned pointer does (temporarily at least) address the issue of not leaking memory (either the pointer is deallocated because the memory is newly allocated, or the memory is given "new life" if its region is merely grown). Quite a wordy thing to try and express that, but I do believe that the original intent of that note was not referring to zero-sizedrealloc
. --Ybab321 (talk) 05:14, 28 March 2024 (PDT)- One possibility that might not be too wordy would be to change sentences like "must be deallocated with free() or realloc()" to "must be deallocated with free() or resized with realloc()". There are a few places where that would have to be done. IMO, it's fine as it is though, especially on the realloc page since that states the behaviour. - Bryce 64.124.34.109 12:02, 3 April 2024 (PDT)
[edit] Bad link to std::get<tuple>
incorrect link to variant related std::get instead of https://en.cppreference.com/w/cpp/utility/tuple/get
- Incorrect link on what page? --Ybab321 (talk) 05:14, 28 March 2024 (PDT)
- ✔ Fixed - it's here, I guess: cpp/utility/tuple/get#Example.) --Space Mission (talk) 15:41, 26 April 2024 (PDT)
- Oh, also here:
- cpp/container/array/get#Example
- cpp/utility/pair/get#Example
- and probably everywhere where std::get<> is used, except when argument of std::get is std::variant, e.g. in here.)
- --Space Mission (talk) 16:00, 26 April 2024 (PDT)
[edit] Should we create an individual page for translation unit
As an important c and cpp concept and the very root of parsing tree, 'Translation Unit' is referred everywhere, however, without an individual page for it. There are pages for translation phases and translation-unit-local, but none for translation unit itself. Should we gather and amalgamate all these information together as a new page to describe it? Yaossg (talk) 05:27, 28 March 2024 (PDT)
- Not against it at all. Not sure how much there is to say beyond "A source file together with all included headers and included source files, less any source lines skipped by preprocessor conditionals, is called a translation unit, or TU. TUs can be separately translated into object files and then later linked to produce an executable program"... not that there's anything wrong with small and easy-to-digest pages. --Ybab321 (talk) 06:23, 31 March 2024 (PDT)
- perhaps cpp/language/translation_phases could provide a linkable definition? That's where it's sort-of introduced. --Cubbi (talk) 09:54, 2 April 2024 (PDT)
[edit] Typo in https://en.cppreference.com/w/c/atomic/ATOMIC_FLAG_INIT
> The value atomic_flag that is not initialized using this macro is indeterminate.
Should be
> The value **of an** atomic_flag that is not initialized using this macro is indeterminate.
[edit] Minor syntax error on the lambda page
Near the bottom of lambda, in the code of the box "If a lambda expression appears in a default argument", functions g6 and g7 have the last parentheses in the wrong place so rather than calling the lambda to produce the default value, they become functions returning functions which isn't allowed. i.e. g6 looks like void g6(int = ([x = 1] { return x; }))();
and not void g6(int = ([x = 1] { return x; })());
which is how g1 through g5 look. - Bryce 64.124.34.109 11:54, 3 April 2024 (PDT)
[edit] Mistake in format string of timespec example
The timespec
example mixed name (tv_sec
) and type (time_t
) of the struct timespec
member in the second output line. It should probably look like this instead:
#include <stdio.h> #include <time.h> #include <stdint.h> int main(void) { struct timespec ts; timespec_get(&ts, TIME_UTC); char buff[100]; strftime(buff, sizeof buff, "%D %T", gmtime(&ts.tv_sec)); printf("Current time: %s.%09ld UTC\n", buff, ts.tv_nsec); printf("Raw timespec.tv_sec: %jd\n", (intmax_t)ts.tv_sec); printf("Raw timespec.tv_nsec: %09ld\n", ts.tv_nsec); }
Possible output:
Current time: 11/24/21 03:10:50.408191283 UTC Raw timespec.tv_sec: 1637723450 Raw timespec.tv_nsec: 408191283
Thanks in advance for fixing this minor issue.
--87.184.167.63 06:23, 4 April 2024 (PDT)
[edit] Arrays of unknown bounds
Arrays of unknown bounds are incomplete types. This is not said on the page about arrays at the top of the page.
[edit] Add remarks about non-overlapping ranges from the standard
According to the standard (https://eel.is/c++draft/numeric.ops#adjacent.difference-8):
Remarks: For the overloads with no ExecutionPolicy, result may be equal to first. For the overloads with an ExecutionPolicy, the ranges [first, last) and [result, result + (last - first)) shall not overlap.
I think this information should be added to this page.
163.116.253.57 12:38, 4 April 2024 (PDT) Andrey
- ✔ Added: see two sentences above Parameters section - quite meaningful remarks. Thanks.) --Space Mission (talk) 09:50, 9 April 2024 (PDT)
[edit] Replace link to reference in page for uniform_real_distribution
In Page https://en.cppreference.com/w/cpp/numeric/random/uniform_real_distribution, replace the invalid link https://hal.archives-ouvertes.fr/hal-03282794/document by https://hal.science/hal-03282794/document 193.52.103.22 23:16, 4 April 2024 (PDT)
- Don't mind changing the link, but they both seem to work for me, what's invalid about that first link? --Ybab321 (talk) 03:53, 5 April 2024 (PDT)
- ✔ Done. The link was updated to the latest version of that fine article — there is versioning over there. Un lien externe a également été ajouté. Kudos to the author.) --Space Mission (talk) 22:06, 6 April 2024 (PDT)
[edit] Typo in Default Constructors Page
Howdy!
I noticed a typo in the syntax section of the "Default Constructors" page. The parameters-list definition misspells parameter in "a parameter list where all paramters..."
2600:387:9:9:0:0:0:46 23:14, 5 April 2024 (PDT) Huperniketes
- ✔ Fixed. Thanks.) --Space Mission (talk) 08:46, 6 April 2024 (PDT)
[edit] Add Slint to the list of open source C++ libraries
In https://en.cppreference.com/w/cpp/links/libs , in the section user interfaces, Slint could be added.
Library | Description | License | Configuration |
---|---|---|---|
Slint | A declarative GUI toolkit to build native user interfaces for desktop, embedded, and microcontrollers. (Src), (Doc) | GPL 3, Royalty-free, or Commercial | cmake |
(While the Slint core library is not implemented in C++, it offers a modern C++20 API and cmake integration)
2003:D2:6720:D700:27A0:5350:1C6A:37B1 23:34, 7 April 2024 (PDT)
- ✔ Done.) --Space Mission (talk) 06:09, 8 April 2024 (PDT)
[edit] try_emplace return value
Hello,
I would like to suggest a change.
The return value case 4-6) of std::map<Key,T,Compare,Allocator>::try_emplace [[10]] is described to be "An iterator pointing at the element that was inserted or updated."
Since the behaviour of try_emplace is analogous to emplace_hint in these cases except for the construction, I believe this is incorrect and should rather state "An iterator pointing at the inserted element, or at the element that prevented the insertion." The corresponding case also holds for the return value 1-3).
--Ladir (talk) 00:43, 11 April 2024 (PDT)
[edit]
I suggest to apply the following change in the page:
https://en.cppreference.com/w/cpp/language/dependent_name
from 'Note that a base class can be the current instantiation if a nested class derives from its enclosing class template.'
to 'Note that an enclosing class template can be the current instantiation if a nested class derives from it.'
Indeed, IMHO, the part '... a base class ... if ... derives from its ...' is ambiguous. If it is a base class, then of course the other one derives from it. Despite I also understand that the nested class might derive, for example, from 'A<typename T::any_type>', I can still state that the actual text made me confused for a bit, because your intended focus is the enclosing class template, for which being a base class is the condition to become the current instantiation.
More generally, I also believe that eh page is ambiguous in stating whether the 'current instantiation' is one specific thing only (e.g., an object?).
[edit] Wrong return type for vector::rbegin()
The return types on the page for vector::rbegin() and friends lack 'reverse' in them. 46.142.195.138 02:05, 11 April 2024 (PDT)
- Whoops, got lost during the "since constexpr" work. Fixed, thanks ✔ Done --Ybab321 (talk) 03:14, 11 April 2024 (PDT)
[edit] Incorrect / misleading output for priority_queue example
The example code for std::priority_queue incorrectly shows the output from printing the contents of the underlying container as being in sorted order. The underlying container is actually in heap order not sorted order. Running the example code shows the actual output is not in sorted order.
To get sorted values out of the heap the example code would need to repeatedly pop elements not just print the contents of the underlying container.
Mattnewport (talk) 11:17, 11 April 2024 (PDT)
- Thanks! The Example was updated. I guess there's no much point in printing the internals of the priority queue (unlike std::stack/std::queue.) ✔ Done. --Space Mission (talk) 00:30, 13 April 2024 (PDT)
[edit] New User. Want to provide an example.
Hi there, I wanted to provide an example for https://en.cppreference.com/w/cpp/utility/functional/greater_void.
How long does it take for someone to no longer be considered a new user?
Fobes (talk) 11:47, 11 April 2024 (PDT) Fobes
[edit] Compound volatile assignments
The "Some uses of volatile are deprecated" paragraph on cpp/language/cv should say that compound volatile assignments have been un-deprecated as of the adoption of P2327R1 and CWG2654 into C++23. --Meiqinyan (talk) 02:50, 12 April 2024 (PDT)
- Not convinced it's worth mentioning, could maybe add to the DR list at the bottom though --Ybab321 (talk) 03:15, 12 April 2024 (PDT)
[edit] Missing requirement in weakly_incrementable
I find that weakly_incrementable is missing default_initializable requirement. Jdgarciauc3m (talk) 09:36, 12 April 2024 (PDT)
- I see no such requirement in the standard --Ybab321 (talk) 15:46, 12 April 2024 (PDT)
[edit] TRuMP
https://en.cppreference.com/w/cpp/language/template_specialization
template<typename>
[[noreturn]] void h([[maybe_unused]] int i);
template<> void h<int>(int i)
{
// [[noreturn]] has no effect, but [[maybe_unused]] has <- it is wrong
}
https://cplusplus.github.io/CWG/issues/2604.html
...
template<typename> [[noreturn]] void h([[maybe_unused]] int i);
template<> void h<int>(int i) {
// Implementations are expected not to warn that the function returns but can
// warn about the unused parameter.
}
...
template<typename>
[[noreturn]] void h([[maybe_unused]] int i);
template<> void h<int>(int i)
{
// [[noreturn]] and [[maybe_unused]] has no effect <- it is correct
}
— Preceding unsigned comment added by 95.105.67.99 (talk • contribs) 02:01:14 & 02:03:54
- "can warn about the unused parameter" is the effect of
[[maybe_unused]]
though --Cubbi (talk)
[edit] Explict list of floating-point exceptions in math pages
I suggest that each page for the math functions should include an explict section, titled something like 'Floating-Point Exceptions', which explicitly lists which FE_* exceptions are applicable to the given math function.
Currently, such exceptions are mentioned throughout the page for the math function, mostly (but not exclusively) in the "Error handling" section. Sometimes, they are only mentioned in the examples section. The 'std::hypot' page, for instance, only explicit shows the "FE_OVERFLOW" in the example code, and only alludes to it in the "Error handling". The same page alludes to "FE_UNDERFLOW", but but does not explicit mentions whether it is returned or not, and does not show example code for it.
For extra consistency, it would be nice if the exceptions are always listed in the same order, via their increasing bitwise value: FE_INEXACT, FE_UNDERFLOW, FE_OVERFLOW, FE_DIVBYZERO, FE_INVALID
Example Sections:
[edit] Floating-Point Exceptions
None
[edit] Floating-Point Exceptions
FE_UNDERFLOW, FE_OVERFLOW
[edit] Floating-Point Exceptions
FE_INEXACT, FE_DIVBYZERO, FE_INVALID
Vladf (talk) 12:06, 15 April 2024 (PDT)
[edit] extern constinit
Posting here as I am a new user.
I thought there used to be a discussion page on cpp/language/constinit discussing this, but that information seems no longer available.
The cpp/language/constinit example using extern doesn't work to prevent initialization checks in Msvc:
extern thread_local constinit int x; int f() { return x; } // no check of a guard variable needed
This, however, does work:
int f() { extern thread_local constinit int x; return x; }
This sort of makes sense, as otherwise there is no way to specify that one function should check and others should not, which is problematic if the variable is declared in a .H file. I haven't verified in the CPP standard.
If anyone has insight into the standardese here (I will also look), we might update the page to discuss the intricacies.
[edit] Bad section in operator delete =
In the page cpp/memory/new/operator_delete, the second section in the introducing array is called replaceable placement deallocation functions, but I think it should be called replaceable non-throwing deallocation functions, to be consistent with the matching section in cpp/memory/new/operator_delete.
--Loic.joly (talk) 09:43, 16 April 2024 (PDT)
[edit] Default-initialization change
On [11]
"Default-initialization of non-class variables with automatic and dynamic storage duration produces objects with indeterminate values (static and thread-local objects get zero initialized)."
Should be changed to:
"Default-initialization of non-class variables and data members with automatic and dynamic storage duration produces objects with indeterminate values (static and thread-local objects get zero initialized)."
as it aligns w/ the example [12]
putii Putii (talk) 03:57, 17 April 2024 (PDT)
- Not sure what that corrects/clarifies, (non-reference) data members are variables --Ybab321 (talk) 09:27, 17 April 2024 (PDT)
- Technically, non-static data members are not variables. (This is also mentioned in cpp/language/basic_concepts.)
- ✔ Done D41D8CD98F (talk) 20:29, 19 April 2024 (PDT)
- Non-reference data members are technically variables https://eel.is/c++draft/basic.pre#def:variable --Ybab321 (talk) 10:14, 20 April 2024 (PDT)
[edit] Group of delete operators (9)-(12) has suspicious name.
On this page: https://en.cppreference.com/w/cpp/memory/new/operator_delete
Right now, it's called "replaceable placement deallocation functions", but AFAICT, they have nothing to do with placement deallocations. Instead it's more like a "replaceable no-throw deallocation functions". Although I don't really like that name, as they all of the others are also "noexcept". They serve in cases of failed construction. So perhaps "replaceable failed-construction deallocation functions"?
[edit] Add note in std::variant's definition of the converting constructor
std::variant's definition of the converting constructor doesn't mention that narrowing and boolean conversions are not considered in the over load resolution. This is only mentioned in the defect reports section and it would arguably help having this mentioned in the definition as well. Something like:
Converting constructor. Constructs a variant holding the alternative type T_j that would be selected by overload resolution for the expression F(std::forward<T>(t)) if there was an overload of imaginary function F(T_i) for every T_i from Types... in scope at the same time, except that an overload F(T_i) is only considered if:
- the declaration T_i x[] = { std::forward<T>(t) }; is valid for some invented variable x. - the expression T_i(std::forward<T>(t)) does not result in a narrowing or boolean conversion
- The list initialisation is what prevents the narrowing conversions. Rewrote to make the narrowing conversions the important bit and the standardese the elaboration ✔ Done --Ybab321 (talk) 03:13, 19 April 2024 (PDT)
[edit] TriviallyCopyable - DR 496
On cpp/named req/TriviallyCopyable, I'd like to propose adding DR 496 to the DR list and editing as follows:
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 496 | C++11 | Volatile trivial types are trivially copyable | made not trivially copyable (reverted in CWG 2094) |
CWG 1734 | C++11 | C++03 POD with deleted non-trivial assignment was not trivial | deleted ctors/operators allowed |
CWG 2094 | C++11 | Volatile scalar types are not trivially copyable (CWG 496, CWG 1746) | made trivially copyable |
It's a bit confusing, since C++11 (n3485) allows volatile, C++14 (n4296) does not allow volatile, and C++17 (n4713) and later again allow volatile.
I'm also not certain how to interpret the "Applied to" column and if/how DRs are applied retroactively, as I can't find any specific documentation on that.
- DR 496 has status CD3 - "DR/DRWP or Accepted/WP issue not resolved in C++11 but included in the Committee Draft advanceed for balloting at the April, 2013 WG21 meeting."
- DR 1734 has status CD4 - "A DR/DRWP or Accepted/WP issue not resolved in C++14 but included in the Committee Draft advanced for balloting at the June, 2016 WG21 meeting."
- DR 2094 has status C++17 - "a DR/DRWP or Accepted/WP issue not resolved in CD4 but included in ISO/IEC 14882:2017."
- "DR" means compilers released after November 2016 (when cwg2094 was "moved to DR") are expected to allow volatile trivial types in -std=c++11, -std=c++14, and all other revision selectors, and we can file bug reports if they don't. It sounds like 2013's cwg496 was only a historic curiosity, not that there's anything wrong with them in dr table. --Cubbi (talk) 20:02, 19 April 2024 (PDT)
[edit] Suggestion for https://en.cppreference.com/w/cpp/utility/variant/visit
Hi, the variant/visit page seems to have some errors perhaps
There's a definition for always_false_v that's defined as a template for unknown reason:
// helper constant for the visitor #3 template<class> inline constexpr bool always_false_v = false;
it's unclear why this is needed.
Could it be defined locally to the function where std::visit is called? You know, don't apply a global solution to a local problem and all that.
EmJayGee (talk) 16:52, 20 April 2024 (PDT)
Thanks, Mike
- It was a workaround for P2593 (which I guess was indeed a global problem), we don't need the
always_false_v
anymore though --Ybab321 (talk) 05:01, 21 April 2024 (PDT)
[edit] UB in std::atoi possible implementation
The suggested implementation has undefined behaviour if converting a string representing std::numeric_limits<int32_t>::lowest(). The late negation in the algorithm will cause signed integer overflow.
- It's OK. If str is "-2147483648", then negative is true and result is -2147483648, so the ternary negative ? result : -result results in the evaluation result, and so the negation is not an issue due to not being evaluated --Ybab321 (talk) 09:55, 22 April 2024 (PDT)
[edit] Is there no Named Requirement here?
The requirements for __range are rather... sharp.
I'm surprised that they aren't expressed as a Named Requirement. Am I missing something? I would have thought that they would be, if not at inception of the range based for but by this point.
This web site is my entry point to the standard, I do not have the energy at this time to bother with all the standardese so if it's there and I haven't seen it, it should be reflected here. If it is there, that would be nice.
Or is this outmoded and with the algorithms and ranges thinking, is the idea that people should not be thinking of using the for statement so much?
It would be good to understand. Our code base is VERY legacy heavy and I want to enable nice features like the ability to use range based for (probably one of the easiest and most obviously valuable advances to make code tidier to see) but it's sometimes difficult to grok when the __range is an invisible adapter vs. the actual iterator that's returned. (I had thought the former but now think the latter.)
- I might be misunderstanding something... __range doesn't really have any requirements other than the range-for wanting to call .begin()/.end() or begin()/end() on it, which I don't think is worthy of a subpage --Ybab321 (talk) 17:07, 22 April 2024 (PDT)
[edit] Is static_assert(false) really allowed since C++11?
Per the CWG, https://cplusplus.github.io/CWG/issues/2518.html it has status C++23 and in GitHub also only mentions fixing the defect in C++23: https://github.com/cplusplus/papers/issues/1251.
Yet, cpp/language/static_assert says this DR is in effect since C++11 and there is no (since C++23) block around the sentence part ", or is evaluated in the context of a template definition and the template is uninstantiated" Yksisarvinen (talk) 15:51, 22 April 2024 (PDT)
- Yeah. The standards folk don't prescribe old revisions of C++ to apply DRs to, those folk live on HEAD perpetually. The C++ revision to which DRs are retroactively applied to and left to the discretion of compiler vendors (especially DRs that formalise existing practice), so you'll notice that in GCC 13, for example, that static_assert(false, ""); is permitted in C++11 mode --Ybab321 (talk) 17:14, 22 April 2024 (PDT)
[edit] 4,5) Missing terminal angle brackets on std::is_constructible_v bullets
In the documentation for constructors 4 and 5, all of the bulleted std::is_constructible_v<... items are missing the terminal '>'.
I'm not cool enough to edit the wiki myself. Cheers!
PunkFloyd (talk) 17:54, 23 April 2024 (PDT)
[edit] Addition to List of Open Source C++ Libraries page
Could this library be added to the testing section of the List of Open Source C++ Libraries Page?
! xhanalib | Testing toolbox for generating random strings and numbers of a specified length. | MIT | header-only; cmake |-
- ✘ Not done. Thanks for the suggested library. However, we cannot add it because it does not meet some (implicit) requirements, such as the number of stars ⭐, in case the project is hosted on GitHub (expected 100 or more ⭐⭐⭐). Maybe later.) --Space Mission (talk) 01:30, 14 May 2024 (PDT)
[edit] std::visit example doesn't compile
The example on the std::visit page only works with c++23 after recent editing. A comment should be added to explain this:
``` else
static_assert(false, "non-exhaustive visitor!"); // requires c++23
```
- C++23 isn't required, but a relatively recent compiler is (GCC 13 or clang 17), this become allowed due to this DR --Ybab321 (talk) 06:53, 13 May 2024 (PDT)
[edit] Right shift UB description incorrect or at least confusing
Over on https://en.cppreference.com/w/cpp/language/operator_arithmetic#Built-in_bitwise_shift_operators, the last sentence reads "If the value of rhs is negative or is not less than the number of bits in lhs, the behavior is undefined." But the two boxes above specify behavior when the value of rhs is not less than the number of bits in lhs (undefined until C++20, but defined since C++20). So I think that the phrase "or is not less than the number of bits in lhs" should be removed from that sentence, shouldn't it?
38.70.3.157 06:49, 13 May 2024 (PDT)
- The box doesn't specify behaviour when the value of rhs is not less than the number of bits in lhs; nothing in the box applies in that case --Ybab321 (talk) 07:01, 13 May 2024 (PDT)
- The pre-C++20 wording is a bit misleading. “For negative a, the value of a >> b is implementation-defined” sounds like there is no UB even if b is negative. I moved the UB condition for rhs right before the revboxes so that the users will be aware of it first. --Xmcgcg (talk) 07:22, 13 May 2024 (PDT)
[edit] std::vector::insert - the type of pos should be iterator instead of const_iterator for C++98
Hello,
According to the N1146 (C++98 final working draft), the insert member function of the std::vector accepts parameter position of type iterator instead of const_iterator (in fact, this applies to other container class, too).
Here is the quotation from the draft:
23.2.4.3 vector modifiers [lib.vector.modifiers]
iterator insert(iterator position, const T& x);
void insert(iterator position, size_type n, const T& x);
template <class InputIterator> void insert(iterator position, InputIterator first, InputIterator last);
Sorry if the formatting isn't great, I'm still getting the hang of the wiki.
--140.114.235.68 08:08, 14 May 2024 (PDT)
- The change was made by LWG issue 149. Its resolution is based on the C++11 wording, which already adopted
const_iterator
parameter types.
- I have tested these overloads in Coliru:
- GCC 13.1 (libstdc++) C++98 mode rejects calling insert() overloads (1,3,4) with const iterators, and insert() returns void if called with non-const iterators.
- Clang 5.0 (libc++) C++98 mode accepts calling insert() overloads (1,3,4) with const iterators, and insert() returns a iterator.
- I will keep the overloads unchanged. Respecting the fact that it is treated as a C++98 DR in some implementations. --Xmcgcg (talk) 19:33, 14 May 2024 (PDT)
- The libstdc++ implements e.g. the std::vector::insert in "/bits/stl_vector.h" file, and loosely (after slight demangling), it looks like this:
#if __cplusplus >= 201103L _GLIBCXX20_CONSTEXPR iterator insert(const_iterator position, const value_type& x); // overload (1) _GLIBCXX20_CONSTEXPR iterator insert(const_iterator position, size_type n, const value_type& x) // (3) { /*...*/ } #else iterator insert(iterator position, const value_type& x); // overload (1) void insert(iterator position, size_type n, const value_type& x) // (3) { /*...*/ } #endif
- The libc++ implements e.g. the std::vector::insert in "vector" file, and approximates to the following:
_LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator position, const_reference x); // (1) _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator position, value_type&& x); // (2) _LIBCPP_CONSTEXPR_SINCE_CXX20 iterator insert(const_iterator position, size_type n, const_reference x); // (3) /*...*/
- So, I also agree that current synopsis is accurate enough (and from API sanity standpoint too), even though formally the overload (1) is not a DR98 in LWG issue 149 (only (3) and (4) are).
- ✔ Done.) --Space Mission (talk) 21:04, 14 May 2024 (PDT)
[edit] std::clamp suggestion
Hi,
The a brief sentence like "std::clamp returns a value within `lo < v < hi`" (or something along those lines) could be added for it to make it a little clearer.
- It's tricky. std::clamp(v, low, high returns a reference to exactly one of
v
,low
orhigh
, not just any value within thelow..high
interval; and std::clamp also can take an arbitrary compare function, which also makes nice simple statements harder to write. Without a loss of precision, I think the current wording is the way to go.
-
The mathematical operation of clamping isn't super complex, so it might suffice to link to wikipedia.Never mind, apparently clamp isn't as popular a function as I thought, I think that increases the importance of providing an intuitive (fast-and-wrong) description of the operation, maybe with a number line graphic(?) Will have to think about it --Ybab321 (talk) 02:43, 16 May 2024 (PDT)
- I went ahead to reword the introductory sentence on cpp/algorithm/clamp. Feel free to revert if you don't like my revision. --D41D8CD98F (talk) 04:22, 16 May 2024 (PDT)
[edit] Typo at https://en.cppreference.com/w/c/language/enum
- // color x = GREEN: // Error: color is not in ordinary name space + // color x = GREEN; // Error: color is not in ordinary name space
[edit] cpp/language/return does not mention [[noreturn]]
Add
Executing the |
(since C++11) |
For attribution, I copied it over from the C reference and changed the C parts to their C++ equivalents. 5.203.228.129 10:34, 17 May 2024 (PDT)
- That sentence is incorrect: the UB scenario is to actually return from a noreturn function, reaching return throw 1; does not return. Therefore, there is no direct relationship between
[[noreturn]]
and return statements. --Xmcgcg (talk) 00:43, 18 May 2024 (PDT)- @User:Xmcgcg Wouldn't that mean that the sentence is incorrect in C as well? What if control flow reaches return f(); where f is a function that never returns? Can you remove the sentence from c/language/return too? As it turns out, the C standard also only says that returning from a noreturn function is UB, it says nothing about executing the return statement. 95.164.181.95 03:05, 18 May 2024 (PDT)
[edit] Next C version is set to C26 in some pages
Template:stdinfo next version number incorrectly has the next C version set to 26. This can be seen in Cppreference:About. --95.164.181.95 11:45, 17 May 2024 (PDT)
- Template:stddoc_latest_draft also behaves incorrectly as can be seen on the same page --95.164.181.95 11:52, 17 May 2024 (PDT)
- ✔ Done? Seems like it was due to missed "lang=" keystroke inside {{stdinfo latest draft docnum}}, {{stdinfo latest draft docdate}}, and {{stdinfo next version number}}. As a result, these tags always worked in C++ mode. I hope it is fixed now.) --Space Mission (talk) 15:57, 17 May 2024 (PDT)
- At least the about page seems fixed. Thanks. 95.164.181.95 18:32, 17 May 2024 (PDT)
[edit] Outdated about page
As long as the site is locked down, the FAQ shouldn't say that anyone can edit. 95.164.181.95 18:30, 17 May 2024 (PDT)
- Striked those sentences, but a description of the current edit policy is still needed. --Xmcgcg (talk) 00:43, 18 May 2024 (PDT)
[edit] cpp/language/union potential distraction for some users
The output shown as "Possible output:" for the first example is only true if the user is running it on a computer with a big endian CPU. Since a significant fraction of the people reading the page will be using little endian CPUs, and of those many won't even be aware of the difference, the shown "Possible output:" is likely to be confusing for them. While the page source indicates that the chosen output is "__ less common output chosen on purpose __", that notation can not be seen unless the user goes to the edit option which most confused users are not likely to do.
I believe there should be some indication on the displayed page describing why the output shown can be correct.
George GanoeGeoganoe (talk) 16:30, 21 May 2024 (PDT)
- The comments in the code listing give both possibilities ("11 or 00, depending on platform", "12340011 or 00115678"), I feel like that's clear enough, though I suppose we could change "platform" to "endianness" --Ybab321 (talk) 02:51, 22 May 2024 (PDT)
[edit] Runtime string
should be equivalent to `return {fmt};` (makes it clearer that it's a runtime-format-string object). As per the paper — Preceding unsigned comment added by 151.192.220.239 (talk • contribs)
- (Assuming that you are referring to cpp/utility/format/runtime_format.) I agree that the mention of return fmt; without curly braces is misleading, though the paper (P2918R2) ends up using return fmt;. --D41D8CD98F (talk) 03:26, 23 May 2024 (PDT)
[edit] Typo in anchor for C header float.h
The link for the text <float.h>
at the top of the page Standard library header <cfloat> includes an anchor that cannot be found on the target page, see following comparison:
-
#Limits_of_floating_point_types
(test:<float.h>
) wrong (current) -
#Limits_of_floating-point_types
(test:<float.h>
) correct with hyphen between floating and point
Thanks in advance for correcting this. --84.138.195.121 02:39, 23 May 2024 (PDT) updated --84.138.195.121 02:43, 23 May 2024 (PDT)
[edit] Suggestion on experimental headers
It would be nice if, let's say, source_location header had the guard to know if the compiler is up to what's needed. But instead of ending there if should have an "else" part to fallback to experimental/source_location if it doesn't.
That way the source wouldn't need to be changed when some experimental header is supported on the compiler used.
[edit]
On this page: https://en.cppreference.com/w/cpp/memory/enable_shared_from_this
Change this:
struct Private{};
To this:
struct Private{ explicit Private() = default; };
Why? Because otherwise the Private parameter in the public constructor can be easily or inadvertently circumvented:
int main() { Best best({}); }
192.147.118.254 05:28, 24 May 2024 (PDT)
- ✔ Yep. Thanks.--Space Mission (talk) 06:01, 24 May 2024 (PDT)
[edit] Small typo in jthread::jthread() example output
There is a typo in the suggested output, "bar::" was used instead of "baz::": https://en.cppreference.com/w/cpp/thread/jthread/jthread
[edit] Original Example
(...) Final value of n is 5 Final value of f.n (foo::n) is 5 Final value of b.n (bar::n) is 0
[edit] Fixed Example
(...) Final value of n is 5 Final value of f.n (foo::n) is 5 Final value of b.n (baz::n) is 0
[edit] Comment on wrong line?
I’m new to cpp, but the comment in the example section “ // the rule for auto makes this ranged-for work” seems to be on the wrong line.
- For context. The "rule for auto" is referring to the deduction of type of the expression {-1, -2, -3} to std::initializer_list<int> (not the int x declaration), in reference to the top of the page "a brace-enclosed initializer list is bound to auto, including in a ranged for loop.".
- Off the top of my head, I didn't think auto or its rules mattered at all for the braced-list in range-for support, so I might fact check that later --Ybab321 (talk) 04:55, 26 May 2024 (PDT)
- there's a matching note in cpp/language/range-for#Notes --Cubbi (talk) 11:06, 26 May 2024 (PDT)
[edit] stdatomic.h - 'see description' points to nothing
#define ATOMIC_BOOL_LOCK_FREE /* see description */ #define ATOMIC_CHAR_LOCK_FREE /* see description */ #define ATOMIC_CHAR16_T_LOCK_FREE /* see description */
They're not mentioned in the description. Should copy a paragraph or two from c/atomic/ATOMIC_LOCK_FREE_consts, maybe?
--98.128.166.54 11:10, 26 May 2024 (PDT)
- Their description is in cpp/atomic/atomic_is_lock_free. The “see description” notations in the synopsis are just simple placements of “see below” in the C++ standard drafts. We do not offer links to the description of macro names due to the limited functionality of source code blocks. --Xmcgcg (talk) 18:41, 26 May 2024 (PDT)
[edit] Document :: on operator_member_access
I'm not sure where to find the "::" operator, but the page https://en.cppreference.com/w/cpp/language/operator_member_access seems like a reasonable place to point to wherever the documentation is. Drf5n (talk) 05:36, 28 May 2024 (PDT)
- it's not really an operator in regular sense (those aren't expressions left and right from it), but we put it in cpp/language/operator_precedence because that's where people expect to see it, and that page links to cpp/language/identifiers#Qualified_identifiers for a summary about it, which further links to cpp/language/qualified_lookup for full detail. --Cubbi (talk) 06:27, 28 May 2024 (PDT)
[edit] Coroutines comma
I think there is an oxford comma missing here, after the word caller
A coroutine is a function that can suspend execution to be resumed later. Coroutines are stackless: they suspend execution by returning to the caller and the data that is required to resume execution is stored separately from the stack.
Should be
A coroutine is a function that can suspend execution to be resumed later. Coroutines are stackless: they suspend execution by returning to the caller, and the data that is required to resume execution is stored separately from the stack.
Otherwise, on first reading it sounds like the coroutines return to the caller and the data!
66.49.219.22 14:40, 28 May 2024 (PDT)
[edit] Outdated example in c/string/multibyte/mbtowc and cpp/string/multibyte/mbtowc
In C23 the type of u8 string literals was changed to char8_t, so the example is outdated and fails to compile with GCC 13.1 (C23). To fix this, you should probably just remove the u8 prefix entirely. In the C++ page, the code is correct, but a comment incorrectly states that using u8 works even though it also doesn't work in C++ with GCC 13.1 (C++23) for the same reason 95.164.181.95 08:14, 29 May 2024 (PDT)
[edit] Missing constructors
For ofstream (and many other pages), I dont see a list of constructors. It should be there. Thanks
Stephen Howe 185.253.178.113 03:07, 30 May 2024 (PDT)
[edit] cpp/utility/launder: contradiction in last code example
In this page https://en.cppreference.com/w/cpp/utility/launder these last two quoted lines from the last example code seem self-contradicting:
int n = base.transmogrify();
is either "undefined behavior" like claimed in the next line or not.
int main() { // Case 1: the new object failed to be transparently replaceable because // it is a base subobject but the old object is a complete object. Base base; int n = base.transmogrify(); // int m = base.transmogrify(); // undefined behavior ...
I think it should be like this
int main() { // Case 1: the new object failed to be transparently replaceable because // it is a base subobject but the old object is a complete object. Base base; Derived derived; int n = base.transmogrify(); // int m = derived.transmogrify(); // undefined behavior ...
Hexcoder- (talk) 01:15, 31 May 2024 (PDT)
- They are not self-contradicting. After the first transmogrify() returns, “base” does not refer to the new “Derived” object constructed in transmogrify() because the old and new objects do not meet the transparently replaceable requirements. Therefore there is an UB in the second transmogrify() if std::launder is not being used. --Xmcgcg (talk) 02:58, 31 May 2024 (PDT)
- Thanks for clarifying! I should have paid more attention to the self-modifying code, appreciated. Hexcoder- (talk) 11:42, 31 May 2024 (PDT)
[edit] cpp/chrono/c/tm missing range for tm_year
Should be 71 - ...
- C only says "years since 1900": https://port70.net/~nsz/c/c11/n1570.html#7.27.1p4 and POSIX says that as well, but elaborates "tm_year is a signed value; therefore, years before 1900 may be represented.": https://pubs.opengroup.org/onlinepubs/9699919799/ --Cubbi (talk) 15:25, 2 June 2024 (PDT)
[edit] Binary search isn't accurate
The operator should be !(value < *it) && !(*it < value). Likewise, the compare version should be updated. Sang Tan Truong (talk) 08:10, 1 June 2024 (PDT)
[edit] Comment for vandalism
why not set a AbuseFilter to disallow clear content/add "rust".--AntiCleanNote (talk) 02:57, 3 June 2024 (PDT)
- Do you know how to get the extension for MediWiki 1.21.2? MediaWiki currently only offers downloads for more recent versions of mw than the one cppreference uses. See https://mediawiki.org/wiki/Special:ExtensionDistributor/AbuseFilter 88.197.79.59 03:29, 3 June 2024 (PDT)
[edit] missing dot at sentence end (in set_constraint_handler_s)
The first paragraph of https://en.cppreference.com/w/c/error/set_constraint_handler_s says:
Configures the handler to be called by all bounds-checked functions on a runtime constraint violation or restores the default handler (if handler is a null pointer)
There is a dot missing after the closing parenthesis.
The title was edited by Space Mission to make it unique.
- ✔ Done. Patched and fixed. Thanks. --Space Mission (talk) 16:19, 11 June 2024 (PDT)
[edit] missing words in description of strnlen_s
The page https://en.cppreference.com/w/c/string/byte/strlen says for the function strnlen_s:
The behavior is undefined if both str points to a character array which lacks the null character and the size of that character array < strsz; in other words, an erroneous value of strsz does not expose the impending buffer overflow.
As with all bounds-checked functions, strnlen_s only guaranteed to be available if __STDC_LIB_EXT1__ is defined by the implementation and if the user defines __STDC_WANT_LIB_EXT1__ to the integer constant 1 before including <string.h>.
To me it looks like in the first paragraph there is an "is" missing, like "the size of that character array /is/ < strsz". (I would even prefer "the size of that character array /is/ less than strsz", but I don't know what is usually used on this site.)
Furthermore, there seems to be an "is" missing in the second paragraph, which I think comes from "https://en.cppreference.com/w/Template:c/ext1_availability": "strnlen_s /is/ only guaranteed".
- Fixed the former ✔ Done. The latter unfortunately requires deciphering the c/ext1_availability template, which I consider prohibitively complex (but maybe someone else will do it) --Ybab321 (talk) 04:12, 13 June 2024 (PDT)
- ✔ Done Fixed Template:c/ext1_availability. --D41D8CD98F (talk) 08:11, 15 June 2024 (PDT)
[edit] Pseudo-random number generation page: typo fix
psuedo -> pseudo
[edit] atexit is not required to be thread-safe in C standard
https://en.cppreference.com/w/c/program/atexit says that the function is thread safe.
It looks (from the page history), that C reference was initially copied from C++ and C++ standard has a note about thread safety. But ISO/IEC-9899:2011 doesn't seem to say anything about that
- as any standard note, https://eel.is/c++draft/support.start.term#note-2 is non-normative, meaning it restates something specified elsewhere. In this case, it's reminding us that it's already guaranteed that all C++ library functions are thread-safe per https://eel.is/c++draft/res.on.data.races . But I think you're right, C library functions are, by default, not thread-safe per https://port70.net/~nsz/c/c11/n1570.html#7.1.4p4 which explains why that c++ note is important. --Cubbi (talk) 08:31, 5 June 2024 (PDT)
- ✔ Done --Space Mission (talk) 00:26, 28 June 2024 (PDT)
[edit] Describing nullopt as uninitialized seems misleading
std::nullopt_t and std::nullopt (and the link from std::optional) are described as having "uninitialized state". When I first read this, I interpreted "uninitialized" to mean "garbage". That is not the case; std::nullopt is a well-specified value meaning "none". I propose that, in all three places, the phrase "with uninitialized state" be replaced with "that does not contain a value" (italics included). This echoes the language used to describe std::optional.
Giggles (talk) 12:20, 5 June 2024 (PDT)
- Agreed. Changed all those descriptions to indicate empty state instead ✔ Done --Ybab321 (talk) 03:48, 13 June 2024 (PDT)
[edit] Add defect report DR1048 for lambdas
The lambda page states that the new return value deduction behavior (changed by N3638) is valid since c++14 but not in c++11, when lambdas with more than one statement had a void return type. According to DR1048, this change should be considered a defect report against c++11.
ThePirate42 (talk) 04:33, 6 June 2024 (PDT)
- Applied the CWG1048 DR changes.✔ Done Unfortunately the rule of lambda return type deduction refers to function return type deduction, so I have to use a footnote to address that. --Xmcgcg (talk) 11:30, 6 June 2024 (PDT)
[edit] Example equal_within_ulps in epsilon page
Hi,
could we please add some more information at the following example (created by user Raniarel): https://en.cppreference.com/w/cpp/types/numeric_limits/epsilon#Example
Questions are:
- what exactly does that do? How does it compare with the writeup here: https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ ? (With which function is it most equivalent with? (AlmostEqualRelative, AlmostEqualUlps, AlmostEqualUlpsAndAbs, AlmostEqualRelativeAndAbs)
- how does it relate to the old example? https://en.cppreference.com/mwiki/index.php?title=cpp/types/numeric_limits/epsilon&oldid=148437#Example
- is this just a fictional example, that could be rewritten to run much faster? Or is this good and fast code, that could be used in production?
- possibly the example should also be expanded, to show behaviour of numbers close to 0; subnormal numbers; etc.
Could someone please write on this talk page, https://en.cppreference.com/w/User_talk:Raniarel , to alert user Raniarel (who wrote the example) of these questions.
PS: here's an interesting paper that shows that boost::math::float_distance is pretty slow (they have an alternative bit-twiddling implementation): https://assets.bitbashing.io/papers/floats.pdf
Thanks.
[edit] 'cpp/thread/jthread/request_stop' has error in example
In the last paragraph, comment "waiting_worker's destructor will call request_stop()" should be "sleepy_worker's destructor will call request_stop()" . Because the previous paragraph called sleepy_worker.request_stop() instead
- no, the comment is talking about waiting_worker. sleepy already stopped the thread so its destructor does nothing. --Cubbi (talk) 11:23, 7 June 2024 (PDT)
Hi, I suggest this example for and_then and or_else pages.
#include <expected> #include <format> #include <print> #include <string> using void_expected = std::expected<void, std::string>; using int_expected = std::expected<int, std::string>; int_expected square(int x) { std::println(" step {}^2", x); return x*x; } int_expected mult_by_2(int x) { std::println(" step {}*2", x); return 2*x; } int_expected div_by_2(int x) { std::println(" step {}/2", x); return x/2; } int_expected minus_2(int x) { std::println(" step {}-2", x); return x-2; } static int divisor = -1; void set_div_by(int x) { divisor = x; } int_expected div_by(int x) { std::println(" step {}/{}", x, divisor); if (divisor != 0) { return x / divisor; } return std::unexpected(std::format("div_by {} error", divisor)); } int main() { std::println("8<- - - - - new way - - - - -"); { set_div_by(1); // ok auto any_function = []() { auto res = square(4).and_then(div_by_2).and_then(div_by).and_then(minus_2); if (!res) std::println(" give wood {}", res.error()); else std::println(" success {}", *res); }; any_function(); set_div_by(0); // fail any_function(); } std::println("8<- - - - - old way - - - - -"); { auto any_function = []() { auto res = square(4); if (!res) std::println(" give wood {}", res.error()); else { if (!(res = div_by_2(*res))) std::println(" give wood {}", res.error()); else { if (!(res = div_by(*res))) std::println(" give wood {}", res.error()); else { if (!(res = minus_2(*res))) std::println(" give wood {}", res.error()); else { std::println(" success {}", *res); } } } } }; set_div_by(1); // ok any_function(); set_div_by(0); // fail any_function(); } return 0; }
Output:
8<- - - - - new way - - - - - step 4^2 step 16/2 step 8/1 step 8-2 success 6 step 4^2 step 16/2 step 8/0 give wood div_by 0 error 8<- - - - - old way - - - - - step 4^2 step 16/2 step 8/1 step 8-2 success 6 step 4^2 step 16/2 step 8/0 give wood div_by 0 error
[edit] Please add John Regehr's nice UB articles as external links to the C++ UB page
Please consider adding links to these pages:
A Guide to Undefined Behavior in C and C++, Part 1 https://blog.regehr.org/archives/213
A Guide to Undefined Behavior in C and C++, Part 2 https://blog.regehr.org/archives/226
A Guide to Undefined Behavior in C and C++, Part 3 https://blog.regehr.org/archives/232
Jjuhl (talk) 14:09, 7 June 2024 (PDT)
Jesper Juhl
[edit] std::chrono:is_clock possible implementation appears incomplete.
The named requirements for Clock specify that C1::is_steady must be a const bool and that C1::now() must return a C1::time_point, among other things. The possible implementation of is_clock, however, does not verify these properties.
- The C++ standard only requires std::chrono::is_clock to check whether the argument satisfy a specific set of “minimal requirements”(the requirements are provided in that page). The implementation is correct, and I added comments to indicate that the expressions
T::is_steady
andT::now()
have no type requirements. --Xmcgcg (talk) 06:08, 8 June 2024 (PDT)
- ✔ Done --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] `std::basic_string` instead of `std::string` (in `std::bitset<N>::to_string`)
In the exceptions section, it says that `std::bad_alloc` may be thrown. However, it says that `std::string`'s constructor will throw it, rather than `std::basic_string`.
[edit] the awk utility utility
The regular expression grammar used by the awk utility utility in POSIX.
Anyone mind deleting the duplicate 'utility'?
--98.128.166.54 10:10, 10 June 2024 (PDT)
[edit] Could we replace all the '\U000000a0' by spaces in every sample code block?
for example, when I try to copy the sample code to an editor:
```cpp struct S { static const int x = 0; // static data member // a definition outside of class is required if it is *odr-used* }; const int& f(const int& r); bool b = true; int n = b ? (1, S::x) // S::x is not *odr-used* here : f(S::x); // S::x is *odr-used* here: a definition is required ``` and compile, it often errors: ``` <source>:6:1: error: extended character is not valid in an identifier 6 | | ^ <source>:6:1: error: '\U000000a0' does not name a type 6 | | ^ <source>:12:13: error: 'f' was not declared in this scope 12 | : f(S::x); // S::x is *odr-used* here: a definition is required | ^ Compiler returned: 1 ```
- reference. Can't reproduce the issue myself, and the text in the wiki page source has no spaces there, so we might not be able to do anything about it. I can see the non-breaking space in the HTML page source though, my browser just copies a normal space into the clipboard I guess. --Ybab321 (talk) 04:27, 11 June 2024 (PDT)
- × --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] std::atomic integral specializations
The page section 'Specialized for integral types only' should be 'Specialized for specific integral types only' as e.g. bool is an integral type and the section does not apply (see N4981 33.5.8.3. for the list of types to which it applies - it'd make sense to refer to these). 2001:4C4D:1E8F:4900:48E5:B9E2:78E9:54D9 08:10, 11 June 2024 (PDT) lorro
- The list is spelt out on the page, there's just an unfortunate huge list of type aliases between this list and the corresponding specialisations. I've moved the type aliases down the page (they're really not interesting enough to warrant being positioned that high in the first place), so I think the result is quite reasonable now. ✔ Done --Ybab321 (talk) 03:32, 13 June 2024 (PDT)
[edit] Suggest clarification on C++17 Compiler support page re: std::filesystem
On the C++17 Compiler Support page, under Library Features heading, there is a row for "File System Library". I have two suggestions for clarifying this row:
1. Append the text " (std::filesystem)" to the first column of this row, so it can be quickly located by users searching for "filesystem".
2. In the 5th column, for AppleClang, the hover text mentions the minimum versions of Xcode required to obtain an AppleClang that supports std::filesystem. However, there is also a runtime requirement of having macOS 10.15 Catalina or newer, because libc++ is linked dynamically and comes with the OS. Older versions of macOS have a libc++.dylib that does not support std::filesystem. I.E. in addition to having a new enough Xcode/AppleClang, you also must target macOS 10.15 or newer. So I suggest appending the text "Must target macOS 10.15 or newer." to the hove text over the AppleClang column on this row.
Mike4Online (talk) 23:47, 11 June 2024 (PDT)
- Added as requested (and I'm taking your word for it) ✔ Done --Ybab321 (talk) 03:18, 13 June 2024 (PDT)
[edit] fold expression with template typename pack
Just thought it would be great one to add, although I dont know if it is intended usage of C++. I use template to create things in my ECS project. And after seeing few fold expressions I tried around it and found out this built. Discord: Advis#4539
This works on my C++17 project I run through cmake.
template<typename T>
void CreateThing()
{
// Create a thing here.
}
template<typename... Ts>
void CreateThings()
{
// Create things one at a time.
(CreateThing<Ts>(), ...);
}
Before this I had one another success with static_cast of my setting type...
struct Setting {};
void AddSetting(Setting* _setting) {}
template<typename... Ts>
void AddSettings()
{
Setting* settings[] = {
static_cast<Setting*>(new Ts)...
};
// As you can see...
for(Setting* setting : settings) {
AddSetting(setting);
}
}
- Neat. I think we could fit in fold expression example of that ilk --Ybab321 (talk) 02:51, 13 June 2024 (PDT)
[edit] tuple/get missing std:: in code
per title
- If you're referring to this example, the
std::
qualification isn't needed thanks to argument dependent lookup. We do tend to add the redundantstd::
qualification anyway just because it invokes the page auto-linker, but the auto-linker is too dumb to work out whichstd::get
overload to link, so thestd::
qualification is explicitly omitted for that example. It's unfortunate, and probably not a problem that will be fixed in the foreseeable future :( ✘ Not done --Ybab321 (talk) 02:37, 13 June 2024 (PDT)- Should the problematic std::get be removed from MediaWiki:Geshi-keyword-list-cpp (similar to how std::move is omitted there)? --D41D8CD98F (talk) 07:30, 15 June 2024 (PDT)
- Yes, no links is better than wrong ones. --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] cpp/algorithm/ranges/find_last missing the explaination for E
Hello:
When I read the https://en.cppreference.com/w/cpp/algorithm/ranges/find_last I'm confused by this line:
Let i be the last iterator in the range [first, last) for which E is true
There is no explanation for E. After reading https://wg21.link/P1223R5 I found that the E is explained in the paper (page 6), but the explanation is not copied to cppreference.
[edit] unordered_map.clear time complexity is wrong
https://en.cppreference.com/w/cpp/container/unordered_map/clear
Here, it says that the time complexity is linear in the size of the container, not in the number of buckets. However, this is not true in practice. See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67922
Suggestion: change complexity description to reflect this, i.e. change "Linear in the size of the container, i.e., the number of elements." to "Linear in the number of buckets of the container".
46.191.225.211 07:16, 15 June 2024 (PDT) grumpy_gordon
- LWG issue 2550 made the intent clear: not linear in the number of buckets. --Xmcgcg (talk) 03:00, 17 June 2024 (PDT)
- ✔ Done --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] In "cpp/named_req/ForwardIterator"
Logical error: The requirement for a and b to be dereferenceable contradicts the first point where "either they are both non-dereferenceable or *a and *b are references bound to the same object.":
Given a and b, dereferenceable iterators of type It
:
- If a and b compare equal (a == b is contextually convertible to true) then either they are both non-dereferenceable or *a and *b are references bound to the same object.
Typo: "value initialized-iterators" should be "value-initialized iterators":
Equality and inequality comparison is defined over all iterators for the same underlying sequence and the value initialized-iterators(since C++14).
[edit] The table of value of value of is_copy_assignable is inconsistent with the possible implementation
It passes first T verbatim whereas the possible implementation adds lvalue reference. Latter matches https://stackoverflow.com/a/19921030 so it is probably correct. is_move_assignable seems to have the same inconsistency.
NJH (talk) 23:13, 16 June 2024 (PDT) NJH
- The difference comes from “referenceable type”, there is a link in the table header. --Xmcgcg (talk) 03:00, 17 June 2024 (PDT)
[edit] Example contains one (possible) mistake in define quard for __cpp_lib_hardware_interference_size
`#ifdef __cpp_lib_hardware_interference_size` is an invalid construction in the example.
According to 15.11, page 455 of
Document Number: N4861 Date: 2020-04-01 Revises: N4849 Reply to: Richard Smith Google Inc cxxeditor@gmail.com Working Draft, Standard for Programming Language C++
the feature test macros should be compared against values in "The names listed in Table 19."
The `#if __cpp_lib_hardware_interference_size >= 201703L` is valid construction.
Konstantin Burlachenko (https://burlachenkok.github.io/)
- 15.11 certainly does list a bunch of feature test macros, but it doesn't seem to suggest that it's invalid to check if they're defined or that integer comparison should be done --Ybab321 (talk) 06:56, 20 June 2024 (PDT)
- × --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] Example for "Function pointer conversions" is unclear and shows the same thing twice
The example for the "Function pointer conversions" subsection on the "Implicit conversions" page is unclear and appears to showcase the same thing twice, just in a more complicated way the second time.
The section is trying to explain simply that a function pointer with a noexcept specification can be converted into a function pointer without one, but not vice versa.
The example decides to show this by:
1) showing that a function pointer to a potentially-throwing function cannot be converted to a pointer to a pointer to a nothrow function
2) showing that a function pointer to a potentially-throwing function cannot be converted to a pointer to a nothrow function when the pointer to the potentially-throwing function is obtained via implicit conversion from a temporary function object
(the example in question, for reference:)
void (*p)(); void (**pp)() noexcept = &p; // error: cannot convert to pointer to noexcept function struct S { typedef void (*p)(); operator p(); }; void (*q)() noexcept = S(); // error: cannot convert to pointer to noexcept function
This doesn't touch on pointer to member function conversion (which is perhaps what the second was attempting to show but was horrifically misguided?) and doesn't show that the opposite (non-throwing to potentially-throwing) does work. A valid takeaway from the example could well be that function pointers of one signature cannot be converted to a function pointer of a different signature under any circumstances, which isn't great considering that the section is explaining the cases where that can happen.
I would suggest changing the example to something like this (perhaps with better names):
void (*f1)(); void (*f2)() noexcept = f1; // error: cannot convert to pointer to noexcept function void (*f3)() = f2; // OK: can convert to pointer to potentially-throwing function struct S { void smf1(); void smf2() noexcept; }; void (S::*mf1)() noexcept = &S::smf1; // error: cannot convert to pointer to noexcept member function void (S::*mf2)() = &S::smf2; // OK: can convert to pointer to potentially-throwing member function
Which shows both the error of converting a potentially-throwing function pointer to a nonthrowing one, the allowed behaviour of converting a nonthrowing function pointer to a potentially-throwing one, and also demonstrates that the same applies to member function pointers, which is what the text above the example is trying to explain
[edit] typo on the rfind page
Hi! On [this page](https://en.cppreference.com/w/cpp/string/basic_string/rfind), there are several typos in the description of range.
It should be [pos, pos + count) instead of [s, s + count), and [pos, pos + Traits::length(s)) instead of [s, s + Traits::length(s)).
- These are not typos. You may check out the definition of iterator-sentinel range.
[
s,
s + count)
means the half-open range starting from the first character of s to the countth character following that character. --Xmcgcg (talk) 09:11, 23 June 2024 (PDT)
- × --Space Mission (talk) 23:29, 27 June 2024 (PDT)
[edit] Example code in cpp/language/try can cause compile error.
Page: cpp/language/try Section: Constructor and destructor try block
The "Ctor/Dtor" of "struct Y" should be "Y()/~Y()", but it's "X()/~X()" in the example code.
[edit] Typo in the header
- floting-point types shall be
- floating-point types
- ✔ Done @ cpp/language/types. Thanks. --Space Mission (talk) 15:28, 24 June 2024 (PDT)
[edit] Typo in example on cpp/utility/optional/optional
In the "Notes" section on cpp/utility/optional/optional, a variable is declared as std::optional<int> op_zero(0); But later is referred to by the name op_0 in the line std::optional<bool> from_int(op_0);.
66.31.14.155 12:01, 26 June 2024 (PDT) mope-life
- ✔ Oops, fixed in this edit, thanks. --Space Mission (talk) 16:43, 26 June 2024 (PDT)
[edit] Typo in toupper page
On https://en.cppreference.com/w/c/string/byte/toupper, the comments identify '\xb8' as "the character Ž in ISO-8859-15 but ´ (acute accent) in ISO-8859-1". These are wrong (it is copied from the tolower page, which uses a different byte value), it should be the lowercase character ž and ¸ (cedilla). --Rmccampbell7 (talk) 14:48, 26 June 2024 (PDT)
[edit] override punctuation
The page for override says:
override is an identifier with a special meaning when used after member function declarators: it's not a reserved keyword otherwise.
That colon should be a semicolon:
override is an identifier with a special meaning when used after member function declarators; it's not a reserved keyword otherwise.
--Metal (talk) 07:24, 28 June 2024 (PDT)
- ✔ Fixed. Thanks. --Space Mission (talk) 09:41, 28 June 2024 (PDT)
[edit] Regarding the wording in the page about C++ namespaces
From the "Using-directives" section:
"From the point of view of unqualified name lookup of any name after a using-directive and until the end of the scope in which it appears, every name from namespace-name is visible as if it were declared in the nearest enclosing namespace which contains both the using-directive and namespace-name."
Can't "the nearest enclosing namespace which contains both the using-directive and the namespace-name" be replaced with "the namespace in which namespace-name is defined"?
A valid using-directive for namespace-name must appear in a scope that is enclosed by the scope in which namespace-name is defined, and the "inner-most" scope that contains namespace-name is the scope in which namespace-name is defined, which will also contain the using-directive.
Are there any subtleties involved here? Anything that I'm overlooking or misunderstanding?
Rajdeep314 (talk) 02:16, 29 June 2024 (PDT)
[edit] cpp/algorithm/bsearch missing semicolon in example
if (p) std::cout << " found at position " << (p - arr.data()) << '\n' else std::cout << " not found\n";
The if block is missing a ; after the '\n'
Steve-downey (talk) 08:46, 2 July 2024 (PDT)
[edit] https://en.cppreference.com/w/cpp/atomic/atomic_flag seems contradictory
Hello,
I'm studying on the concurrency support library and I found the example to be contradictory in the atomic_flag page. The first sentence says that atomic_flag is guaranteed to be lock free, however the example names it 'lock' and comments in the code example give me the impression that it is acquiring locks.
Perhaps removal of these comments and renaming for brevity could be recommended.
Thanks
- The example is indeed acquiring (and releasing) a lock, specifically, a spinlock, whose implementation is what it is demonstrating. --Cubbi (talk) 12:51, 2 July 2024 (PDT)
[edit] signature wrong
signature of (1) and (2) should be
atomic& operator=( T desired ) noexcept; (1) (since C++11)
atomic& operator=( T desired ) volatile noexcept; (2) (since C++11)
2001:7C0:2015:210:0:0:F:77 04:55, 3 July 2024 (PDT)
- The signatures look correct to me https://eel.is/c++draft/atomics.types.operations#lib:operator=,atomic --Ybab321 (talk) 06:03, 3 July 2024 (PDT)
[edit] Fix format_to_n example
Original example has a bad null terminator logic.
Add:#include <algorithm> Change null termination to: // Add terminator to buffer. buffer[std::min(static_cast<std::size_t>(result.size), max_chars_to_write)] = '\0';
Full updated example:
#include <algorithm> #include <format> #include <iostream> #include <string_view> int main() { char buffer[64]; for (std::size_t max_chars_to_write : {std::size(buffer) - 1, 23uz}) { const auto result = std::format_to_n( buffer, max_chars_to_write, "Hubble's H{2} {3} {0}{4}{1} km/sec/Mpc.", // 24 bytes w/o formatters 71, // {0}, occupies 2 bytes 8, // {1}, occupies 1 byte "\u2080", // {2}, occupies 3 bytes, '₀' (SUBSCRIPT ZERO) "\u2245", // {3}, occupies 3 bytes, '≅' (APPROXIMATELY EQUAL TO) "\u00B1" // {4}, occupies 2 bytes, '±' (PLUS-MINUS SIGN) ); // 24 + 2 + 1 + 3 + 3 + 2 == 35, no trailing '\0' // Add terminator to buffer. buffer[std::min(static_cast<std::size_t>(result.size), max_chars_to_write)] = '\0'; const std::string_view str{buffer, result.out}; // uses C++20 constructor std::cout << "Buffer until '\\0': \"" << buffer << "\"\n" << "Max chars to write: " << max_chars_to_write << '\n' << "result.out offset: " << result.out - buffer << '\n' << "Untruncated output size: " << result.size << "\n\n"; } }
— Preceding unsigned comment added by Mailnew4ster (talk • contribs) 2024-07-04 22:35:16
— Reformatted using MediaWiki tags. --Space Mission (talk) 03:34, 5 July 2024 (PDT)
- I don't see any issue with the null termination of the example as written. ✘ Not done --Ybab321 (talk) 02:52, 9 July 2024 (PDT)
[edit] Where is rsize_t defined?
https://en.cppreference.com/w/c/error says: <stdint.h>, albeit RSIZE_MAX
is defined in <stdlib.h>
But rsize_t
is not mentioned on https://en.cppreference.com/w/c/types/integer
The link "<stdlib.h>" at https://en.cppreference.com/w/c/header goes to https://en.cppreference.com/w/c/program where neither rsize_t
nor RSIZE_MAX
is mentioned.
rsize_t
is used at https://en.cppreference.com/w/c/string/byte/strcpy but not linked, but size_t
is linked. :-/
- https://en.cppreference.com/w/c/error#Bounds_checking --Ybab321 (talk) 02:05, 8 July 2024 (PDT)
[edit] Fix format_to_n example - the problem
See my suggestion above that was rejected.
It was rejected - "I don't see any issue with the null termination of the example as written" - but you can easily see the issue even on the website: https://i.imgur.com/mV2os1U.png
— Preceding unsigned comment added by Mailnew4ster (talk • contribs) 22:03:33
- ✔ Done.) That's all about this Bug 110990 - `format_to_n` returns wrong value in stdlibc++ being fixed in GCC v.13.3. The format_to_n example relies on correct behavior, whilst current online gcc version on this site is only GCC v.13.1. --Space Mission (talk) 13:09, 9 July 2024 (PDT)
[edit] Wrong "Possible implementation" for std::add_lvalue_reference, std::add_rvalue_reference
Hi,
The "Possible implementation" is not working actually for std::add_lvalue_reference, std::add_rvalue_reference (https://en.cppreference.com/w/cpp/types/add_reference).
The exhibited implementation can't work for "const void", "volatile void" or "const volatile void" types:
static_assert(not is_same_v<const void, add_lvalue_reference_t<const void>>, "bad"); static_assert(not is_same_v<volatile void, add_lvalue_reference_t<volatile void>>, "bad"); static_assert(not is_same_v<const volatile void, add_lvalue_reference_t<const volatile void>>, "bad");
The result of above "add_lvalue_reference_t" are all "void" instead.
The reason is that a function will translate the return type "const/volatile void" to void:
const void f(); static_assert(is_same_v<void, decltype(f())>, "const void -> void");
The following suggested implementation is from GCC 14:
namespace detail { template<typename T, typename = void> struct __try_lval_ref { using type = T; }; template<typename T> struct __try_lval_ref<T, std::void_t<T&>> { using type = T&; }; template<typename T, typename = void> struct __try_rval_ref { using type = T; }; template<typename T> struct __try_rval_ref<T, std::void_t<T&&>> { using type = T&&; }; } template<typename T> struct add_lvalue_reference { using type = detail::__try_lval_ref<T>::type; }; template<typename T> struct add_rvalue_reference { using type = detail::__try_rval_ref<T>::type; };
Also, I'd suggest to add the following code in the examples:
static_assert(is_same_v<const void, add_lvalue_reference_t<const void>>, "void has no ref"); static_assert(is_same_v<volatile void, add_lvalue_reference_t<volatile void>>, "void has no ref"); static_assert(is_same_v<const volatile void, add_lvalue_reference_t<const volatile void>>, "void has no ref"); static_assert(is_same_v<const void, add_rvalue_reference_t<const void>>, "void has no ref"); static_assert(is_same_v<volatile void, add_rvalue_reference_t<volatile void>>, "void has no ref"); static_assert(is_same_v<const volatile void, add_rvalue_reference_t<const volatile void>>, "void has no ref");
Regards,
Zhao
- The implementation seems to pass the suggested static asserts https://godbolt.org/z/bxc5jvdMK. I think your speculation missed the use of
type_identity<T>
as the return type oftry_add_lvalue_reference
, not to be confused withtype_identity<T>::type
, so the cv qualification isn't stripped away --Ybab321 (talk) 04:18, 11 July 2024 (PDT)
[edit] Clarify vector move assignment
In https://en.cppreference.com/w/cpp/container/vector/operator%3D:
If std::allocator_traits<allocator_type>::propagate_on_container_move_assignment::value is true, the allocator of *this is replaced by a copy of that of other.
Should be "replaced by a move"
--Oracle (talk) 04:00, 11 July 2024 (PDT)
- I believe copy is correct, I think this is the requirement (note that move assignment operator is a member function and isn't one of the exceptions aforelisted). Experimentally speaking, compilers are indeed doing a copy --Ybab321 (talk) 04:36, 11 July 2024 (PDT)
[edit] Mistake in std::projected_value_t definition
C++26's projected_value_t is defined as:
std::remove_cvref_t<std::invoke_result<Proj&, std::iter_value_t<I>&>>
While it shoud be defined as:
std::remove_cvref_t<std::invoke_result_t<Proj&, std::iter_value_t<I>&>>
(invoke_result_t, not invoke_result)
[edit] Add an awesome external tutorial to coroutine page.
This coroutine tutorial is awesome, can we add this to the end of this page? https://www.chiark.greenend.org.uk/~sgtatham/quasiblog/coroutines-c++20/
- Looks alright at a glance, added to the coroutines page ✔ Done --Ybab321 (talk) 04:43, 13 July 2024 (PDT)
[edit] std::integer_sequence code improvement
a2t function template, last template parameter is unnecessary.
The same functionality can be satisfy with the following code:
template<typename T, std::size_t N> auto a2t(const std::array<T, N>& a) { return a2t_impl(a, make_index_sequence<N>{}); }
— Preceding unsigned comment added by 2a02:830a:b20c:8c00:a8d0:27f2:d0cc:a12e (talk • contribs) 2024-07-15 @ 01:24:11
- Technically, you're right, but from the other side the present design gives us more flexibility, as you can see in recent update of example, that is, we can "shuffle" the input passing an arbitrary integer sequence:
std::array array{1, 2, 3, 4}; auto tuple = array_to_tuple<int , 4, std::integer_sequence<std::size_t, 1, 0, 3, 2>>(array); // array == (1, 2, 3, 4) // tuple == (2, 1, 4, 3)
- ✔ Done. --Space Mission (talk) 06:11, 15 July 2024 (PDT)
[edit] iota
I recently came across the iota functionality. Which should be (but isn't) a simplification for a standard 'for' loop. It has the good intention to avoid detailed for loop instructions that can be (for an inexperienced programmer) error prone and I agree with intend of it. Unfortunately the cppreference page is totally unreadable. It seems to be written for layers. Even I as very experienced programmer need to "decrypt " it. I am sure a rewrite in simpler understandable way would appreciated by many. Thanks in advance.
89.205.134.36 09:12, 15 July 2024 (PDT)
- Assuming you're talking about
views::iota
, it is indeed very complex. The complexity of ranges library in general is prohibitively high for an inexperienced C++ programmer, I don't think there's much we can do about that other than hope to provide some nice examples (which that page seems to have at least). The standard for loop is as simple as possible, so should be preferred for the purposes of simple looping code (even by C++ gurus) --Ybab321 (talk) 10:12, 15 July 2024 (PDT)
[edit] find_last
The find_last
example code compares a non-value-initialized iterator with a value-initialized iterator. This is not actually permissible given the semantic requirements of forward_iterator
:
The domain of for forward iterators is that of iterators over the same underlying sequence.
However, value-initialized iterators of the same type may be compared and shall compare equal to other value-initialized iterators of the same type.
Note that the domain of for non-value-initialized forward iterators does not include value-initialized forward iterators of the same type.
Strega-nil (talk) 17:02, 16 July 2024 (PDT)
- I think what you probably mean is the possible implementation. A std::optional object is used now instead of a value-initialized forward iterator.✔ Done --Xmcgcg (talk) 20:44, 16 July 2024 (PDT)
[edit] Standard support
std::map::at is supported since C++11 only, so there should be '|since=c++11' comment.
- × Nope, std::map::at() has been ported to C++98, as you can see in the Defect reports section that links to LWG issue 464.) --Space Mission (talk) 06:31, 22 July 2024 (PDT)
[edit] minor typo fix
On the page cpp/language/scope, typo "hander" should be "handler" in the text "compound statement that is not the compound-statement of a hander".
-- Liginitylee (talk) 19:57, 23 July 2024 (PDT)
[edit] Incorrect description of array to pointer conversion
This section c/language/array#Array_to_pointer_conversion has two problems:
1. An expression can't be the operand of _Alignof, in the linked article c/language/_Alignof it shows that it strictly takes a type operand so an expression operand just wouldn't be valid.
2. Not just lvalue expressions are subject to array to pointer conversion.
Section 6.3.2.1 "Lvalues, arrays, and function designators" Paragraph 3 ISO/IEC 9899:2018
Except when it is the operand of the sizeof operator, or the unary & operator, or is a string literal used to initialize an array, an expression that has type "array of type" is converted to an expression with type "pointer to type" that points to the initial element of the array object and is not an lvalue. If the array object has register storage class, the behavior is undefined.
The standard intentionally says "an expression with type ..." not "an lvalue expression with type ..." or "an lvalue with type ...". This allows for example for the following code to be valid:
#include<stdio.h> struct foo{ char c[32]; }bar(void){ return(struct foo){"abc"}; } int main(void){ puts(bar().c); }
The entry mentioning _Alignof should be deleted and the word lvalue should be deleted. It is worth noting that the linked article c/language/value_category says:
The following expressions are non-lvalue object expressions:
...
member access operator (dot) applied to a non-lvalue structure/union, f().x, (x,s1).a,
...
Note that a struct/union rvalue that has a member (possibly nested) of array type does in fact designate an object with temporary lifetime. This object can be accessed through lvalue expressions that form by indexing the array member or by indirection through the pointer obtained by array-to-pointer conversion of the array member.
This article acknowledges that array to pointer conversion can happen to non-lvalue expressions of array type.
[edit] Possible implementation and examples for std::is_(nothrow_)swappable(_with)
Hi, the std::is_swappable family is missing possible implementation and examples: https://en.cppreference.com/w/cpp/types/is_swappable
I'm studying GCC 14 source code and wrote a working version. So share it here in case useful:
Possible implementation:
namespace detail { using std::swap; template<typename T, typename U> using __swap_void_t = decltype(swap(std::declval<T>(), std::declval<U>())); template<typename T, typename U, bool B = noexcept(swap(std::declval<T>(), std::declval<U>()))> constexpr bool __nothrow_swap_void_v = B; template<typename T, typename U, typename = __swap_void_t<T, U>, typename = __swap_void_t<U, T>> std::true_type __check_swap(int); template<typename T, typename U> std::false_type __check_swap(...); template<typename T, typename U> std::bool_constant<__nothrow_swap_void_v<T, U> && __nothrow_swap_void_v<U, T>> __check_nothrow_swap(int); template<typename T, typename U> std::false_type __check_nothrow_swap(...); } template<typename T, typename U> struct is_swappable_with : decltype(detail::__check_swap<T, U>(0)) {}; template<typename T, typename U> struct is_nothrow_swappable_with : decltype(detail::__check_nothrow_swap<T, U>(0)) {}; template<typename T> struct is_swappable : std::bool_constant<std::is_swappable_with_v<T&, T&>> {}; template<typename T> struct is_nothrow_swappable : std::bool_constant<std::is_nothrow_swappable_with_v<T&, T&>> {};
Examples:
struct A {}; struct B { B(); B(B&&) = delete; }; struct C {}; void swap(C&, C&) noexcept(false); // Both are needed to make A and C swappable with. // But they are NOT nothrow swappable with because one of the following is not. void swap(A&, C&) noexcept; void swap(C&, A&); int main() { static_assert(std::is_swappable<int>::value); static_assert(not std::is_swappable<const int>::value); static_assert(std::is_swappable<volatile int>::value); static_assert(std::is_swappable_v<A>); static_assert(not std::is_swappable_v<B>); // B is NOT move constructible static_assert(not std::is_swappable_with<int, int>::value); static_assert(std::is_swappable_with<int&, int&>::value); static_assert(not std::is_swappable_with<int&&, int&&>::value); static_assert(not std::is_swappable_with_v<A&, B&>); static_assert(std::is_swappable_with<A&, C&>::value); static_assert(std::is_nothrow_swappable<int>::value); static_assert(std::is_nothrow_swappable_v<A>); static_assert(not std::is_nothrow_swappable_v<C>); static_assert(std::is_nothrow_swappable_with<int&, int&>::value); static_assert(not std::is_nothrow_swappable_with<A&, C&>::value); }
--Zhao (talk) 02:39, 26 July 2024 (PDT)
[edit] Please add my library
! Caitlyn::Json | C++11/14/17 JSON serializing, C++ | GPL-3.0 | cmake |-
Szawrowski (talk) 03:43, 26 July 2024 (PDT)
[edit] Update clang's C23 support
Template:c/compiler support/23 should be updated to reflect https://clang.llvm.org/c_status.html#c2x. In particular, N3007 were added in 18, N3042 was added in 17, not 16, and N2653, N3017 and N3018 were added in 19. 2A02:587:7E01:8A00:25FF:4776:D1D7:E6F9 06:05, 28 July 2024 (PDT)
[edit] std::basic_string iterator invalidation
Suggested addition:
References, pointers, and iterators referring to the elements ofbasic_string
may be invalidated by:
- Passing a non-
const
reference to it into a standard library function.
- Calling non-
const
member functions, exceptoperator[]
,at
,back
,begin
,data
,end
,front
,rbegin
,rend
.
Leduyquang753 (talk) 07:46, 31 July 2024 (PDT)
- that's https://eel.is/c++draft/string.classes#string.require-4 and I agree it's a reasonable note to make; calling
getline(cin, str)
may invalidatestr
's iterators/references. --Cubbi (talk) 11:56, 31 July 2024 (PDT)
[edit] Amend example
#include <iostream> struct S { void f() & { std::cout << "lvalue\n"; } void f() && { std::cout << "rvalue\n"; } void f() const & { std::cout << "c-lvalue\n"; } void f() const && { std::cout << "c-rvalue\n"; } }; int main() { S s; s.f(); // prints "lvalue" std::move(s).f(); // prints "rvalue" S().f(); // prints "rvalue" const S& t = s; t.f(); // prints "c-lvalue" std::move(t).f(); // prints "c-rvalue" }
[edit] Typo in return value of std::clamp
In std::clamp you made typo in return value article by saying that value should be less than {hi}. Then it would be returned.
Fix: change word less in {hi} case to greater
Better visualization->
Return Value:
If v is less than lo, it returns lo.
If v is greater than hi, it returns hi.
Otherwise, it returns v.
- The current wording says "hi if hi is less than v", I think you mistakenly swapped hi and v in your reading. --Ybab321 (talk) 02:30, 8 August 2024 (PDT)
[edit] Add a note for bfloat16_t
According to https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116319
Andrew Pinski confirms for std::(std::bfloat16_t, std::bfloat16_t, std::bfloat16_t) is not really " Computes x * y + z as if to infinite precision and rounded only once to fit the result type."
Good to add a note for it.
[edit] errata for unqualified lookup page
On the unqualified lookup page[14],
[edit] Issue 1
Under the dominance in virtual inheritance section, the description text should change class name 'C' to 'D' to match the example followed.
- It's actually more useful to be able to refer to C as the in-progress lookup set construction; there's a distinction between C and D in the "C++11 rules" prose of the example ✘ Not done --Ybab321 (talk) 12:01, 14 August 2024 (PDT)
[edit] Issue 2
And the following description text, talking about the unambiguity of members in non-virtual base subobject, class name 'B' should be change to 'D' to match the following example.
- Changed the example instead, B is a pretty reasonable notation for a base class ✔ Done --Ybab321 (talk) 12:01, 14 August 2024 (PDT)
--Pauljay (talk) 04:08, 11 August 2024 (PDT)
[edit] std::ignore is constexpr since C++17, not since C++14
In https://en.cppreference.com/w/cpp/utility/tuple/ignore it is stated that std::ignore is constexpr since C++14, however, that is not correct, in the C++14 Standard it is still just const, it is in C++17 when it is constexpr (and inline, that is correct).
- It is LWG issue 2773 (check out the “Defect Reports” section on the bottom). It is a defect, which means it is the intention of the standard C++ commitee to make
std::ignore
constexpr in C++14, but the related wording was not updated. --Xmcgcg (talk) 08:23, 12 August 2024 (PDT)
[edit] A typo on the ‘c/language/function definition’ page
The first code listing in the Explanation section has a typo: The return statement in the sum() function ends with a colon instead of a semicolon.
[edit] Small typo in cpp/ranges/take_view#Example
Hey I just found a small typo in the code example: This comment: // safely takes only upto min(n, num.size()) elements: should be: // safely takes only upto mins(n, num.size()) elements:
- Not sure what page you're referring to --Ybab321 (talk) 10:57, 14 August 2024 (PDT)
- ✔ Done. It's here. The id num should actually be nums.) --Space Mission (talk) 14:27, 14 August 2024 (PDT)
[edit] Typo on the page cpp/language/operator_incdec
Hey I see a typo on the page cpp/language/operator_incdec under the subheading "Built-in prefix operators", the word qualified is misspelled as qialified 3 times. -- Nickk752 (talk) 12:42, 14 August 2024 (PDT)
- ✔ Fixed. Thanks.) --Space Mission (talk) 14:31, 14 August 2024 (PDT)
[edit] Proper Vector Slicing
Is there a plan to implement vector (or any container) slicing like the kind in Python? I had to implement it in lib I'm working on and wondering if we can add it it STL.
Gxtsby (talk) 02:39, 15 August 2024 (PDT)
- There's std::span, which pretty much gets the job done. --Ybab321 (talk) 07:32, 15 August 2024 (PDT)
[edit] mutex()->unlock() should not throw exceptions in unique_lock::unlock
The unique_lock page:
https://en.cppreference.com/w/cpp/thread/unique_lock
states that:
Mutex - the type of the mutex to lock. The type must meet the BasicLockable requirements
A BasicLockable type's unlock method must throw no exceptions: https://en.cppreference.com/w/cpp/named_req/BasicLockable
However, the unique_lock's unlock page:
https://en.cppreference.com/w/cpp/thread/unique_lock/unlock
says under its Exceptions section:
Any exceptions thrown by mutex()->unlock() (std::mutex::unlock does not throw, but user-provided Mutex type could).
Since unique_lock requires its mutex to be BasicLockable, the mutex it holds should not throw any exceptions on unlock - user-provided included. If I've understood it correctly then, I think this sentence should be updated to reflect that fact?
- yep, I think you're right; per https://eel.is/c++draft/thread.lock.unique#general-1.sentence-5 -> https://eel.is/c++draft/thread.req.lockable.basic#5.sentence-1 --Cubbi (talk) 13:27, 16 August 2024 (PDT)
[edit] Broken link in std::formatter
Hi,
In the frame "(since C++23)" in the page std::formatter, the link with the text "escaped and quoted" is broken. It should refer to the spec page: Standard format specification #Formatting escaped characters and strings.
Thanks!
- ✔ Done Good catch. The link became broken when the page was split into two parts. It's fixed now.) --Space Mission (talk) 15:13, 16 August 2024 (PDT)
[edit] example code doesn't work
std::chrono::duration_cast<std::chrono::microseconds>(end - start)
should be replaced by
std::chrono::duration_cast<std::chrono::microseconds>(end - start).count()
the operator << doesn't seem to work with a duration object. 2003:EE:9705:3E00:6AC9:3C5:3EE2:B7F0 07:46, 18 August 2024 (PDT)
- We have a non-member operator<< for std::chrono::duration since C++20. --Xmcgcg (talk) 19:31, 18 August 2024 (PDT)
[edit] Small typo fix
The link https://en.cppreference.com/w/cpp/language/default_comparisons has an extra 'the' in "The the non-static data members of C, in declaration order."
Leezaj (talk) 13:35, 18 August 2024 (PDT)leezaj
[edit] Suggests adding a note that timing when parameter objects are destroyed is implementation-defined
The section Temporary object lifetime [15] seems indicate that parameter objects are destroyed at the end of full-expression, which is not correct on some implementations(e.g. MSVC).
How about adding this:
It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.
Related:
CWG1880: https://cplusplus.github.io/CWG/issues/1880.html
P0135R1: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0135r1.html
- Parameter objects are not temporary objects, their lifetimes are not mentioned in the “Temporary object lifetime” section either. Their lifetimes are described in the “Built-in function call operator” section:
It is implementation-defined whether a parameter is destroyed when the function in which it is defined exits or at the end of the enclosing full-expression. Parameters are always destroyed in the reverse order of their construction.
[edit] Minor Code Error in std::tanh(x) example
https://en.cppreference.com/w/cpp/numeric/math/tanh should say
<< "tanh(x)*sinh(2*x)-cosh(2*x) = "
instead of
<< "tanh(x)*sinh(2*x)-cos(2*x) = "
in the example
165.225.124.176 08:20, 20 August 2024 (PDT)
[edit] Glaze json library
I think an excellent addition to your list of C++ libs would be Glaze for serialization to/from json.
Link to glaze: https://github.com/stephenberry/glaze
2600:1008:A130:2253:19B3:848E:1A62:23CB 14:21, 24 August 2024 (PDT)Tony Antonucci
- ✔ Added: cpp/links/libs#Configuration:JSON. Thanks.) --Space Mission (talk) 00:12, 25 August 2024 (PDT)
[edit] Typo in uses_allocator
Under Specializations heading, change "is any" to "if any".
— Preceding unsigned comment added by 138.217.206.118 (talk • contribs) @ 01:11:30
- It was ✔ Fixed.) --Space Mission (talk) 12:24, 26 August 2024 (PDT)
[edit] Updation of C++23 compatibility of Intel compiler
Hi, recently I tried to compile my C++23 project using intel icpx compiler which previously didn't support "deducing this" and a lot more as of 2024.1 (last I tried). Upon updating the compiler to newer version "Intel(R) oneAPI DPC++/C++ Compiler 2024.2.1 (2024.2.1.20240711)" I was able to compile my project using new compiler.
Going roughly through the release notes turns out that 2024.2 started supporting clang-18 frontend which might have resulted in this partial support.
[edit] std::unique_copy available since c++98 not c++17
Dear cppreference maintainers,
If I understand correctly std::unique_copy was first introduced in the c++98 It also works when I try to compile on something like cpp.sh.
The webpage does not reflect this function being available from that moment because it says (since c++ 17), (since c++ 20), etc.
Am I wrong or does it need an update?
- std::unique_copy has indeed been around forever. The ExecutionPolicy overloads became available in C++17 onwards, the other overloads became constexpr in C++20, I think you must have skipped over the word "constexpr". --Ybab321 (talk) 15:03, 29 August 2024 (PDT)
[edit] Improve the crtp pattern to
Change the crtp pattern to
makeing it impossible for the user to have UB
Base<D1> b1; b1.name(); // does not compile
84.142.210.134 05:52, 30 August 2024 (PDT)
The code was formatted with MediaWiki by --Space Mission (talk) 13:42, 31 August 2024 (PDT)
- ✔ Done. The protected: Base() = default; idiom was incorporated. Thanks.) --Space Mission (talk) 13:42, 31 August 2024 (PDT)
Error on line 20 of the Example section of this post: basic_string/insert
```
// insert(size_type index, string const& str) s.insert(6, "a"s); // Should be "s.insert(6, "a"s);" assert("Exemplar" == s);
``` MountainC (talk) 02:54, 1 September 2024 (PDT)
- You appear to have written the same code twice, in both cases the same as the current code in the example. --Ybab321 (talk) 04:54, 1 September 2024 (PDT)
[edit] Misleading language on the cpp/language/coroutines page
The cpp/language/coroutines page has the following misleading language:
> Note that because the coroutine is fully suspended before entering awaiter.await_suspend(), that function is free to transfer the coroutine handle across threads, with no additional synchronization.
This language suggests that storing a coroutine handle automatically synchronizes with a subsequent load of the coroutine handle, such that, for instance, it would be okay to use std::memory_order_relaxed to transfer the handle. There is no support for such an implication in the language specification. I suggest rewording this sentence while avoiding use of the loaded term synchronization. For example:
Note that the coroutine is fully suspended before entering. Its handle can be shared with another thread and resumed before the `await_suspend` function returns. (Note that the default memory safety rules still apply, so if a coroutine handle is shared across threads without a lock, the awaiter should use at least release semantics and the resumer should use at least acquire semantics.)
--Wikweb (talk) 11:18, 4 September 2024 (PDT)
- The aforementioned text in
co_await
section was updated.) ✔ Done --Space Mission (talk) 15:19, 4 September 2024 (PDT)
[edit] Error in https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence
On https://en.cppreference.com/w/cpp/atomic/atomic_thread_fence replace "except for std::atomic_thread_fence(std::memory_order::seq_cst)" with "except for std::atomic_thread_fence(std::memory_order_seq_cst)".
62.96.65.119 04:26, 5 September 2024 (PDT)
- ✔ Done: updated.) --Space Mission (talk) 05:37, 5 September 2024 (PDT)
[edit] Clarification needed on the range of values a signed bit-field can represent in C
In C, the range of values a signed bit-field can represent follows the same rules as signed integers and is implementation-defined i.e. signed bit-field of width 3 can hold either -4..3 or -3..3. I couldn't find exact clarification in the C standard except of the vague:
A bit-field is interpreted as a signed or unsigned integer type consisting of the specified number of bits
However, I did find an example:
The following obscure constructions
typedef signed int t; typedef int plain; struct tag { unsigned t:4; const t:5; plain r:5; };
declare a typedef name t with type signed int, a typedef name plain with type int, and a structure with three bit-field members, one named t that contains values in the range [0, 15], an unnamed const-qualified bit-field which (if it could be accessed) would contain values in either the range [−15, +15] or [−16, +15], and one named r that contains values in one of the ranges [0, 31], [−15, +15], or [−16, +15]. (The choice of range is implementation-defined.) ...
Since C23, two's complement is forced and the ranges are no longer implementation-defined.
I propose to make a change at https://en.cppreference.com/w/c/language/bit_field. Change this paragraph:
Bit-fields can have only one of these three(until C99) – four(since C99)(until C23) types (possibly const or volatile qualified):
- unsigned int, for unsigned bit-fields (unsigned int b:3; has the range 0..7)
- signed int, for signed bit-fields (signed int b:3; has the range -4..3)
- int, for bit-fields with implementation-defined signedness (Note that this differs from the meaning of the keyword
int
everywhere else, where it means "signed int"). For example, int b:3; may have the range of values 0..7 or -4..3.
to this:
Bit-fields can have only one of these three(until C99) – four(since C99)(until C23) types (possibly const or volatile qualified):
- unsigned int, for unsigned bit-fields (unsigned int b:3; has the range 0..7)
- signed int, for signed bit-fields (signed int b:3; has the range -4..3 or -3..3(until C23))
- int, for bit-fields with implementation-defined signedness (Note that this differs from the meaning of the keyword
int
everywhere else, where it means "signed int"). For example, int b:3; may have the range of values 0..7 or -4..3 or -3..3(until C23).
("or -3..3(until C23)" was added twice)
--A-sum-duma (talk) 02:16, 6 September 2024 (PDT)
- This site doesn't tend to acknowledge the existence of non 2s complement integer representation other than a passing mention. I don't think it would really help anyone to add that revbox detail. --Ybab321 (talk) 13:10, 7 September 2024 (PDT)
[edit] Discussion on common_type
struct base{}; struct d1:base{}; struct d2:base{}; #include <type_traits> static_assert(std::is_same<std::common_type_t<base, d1,d2>, base>::value,"type is base"); static_assert(std::is_same<std::common_type_t<d2,d1,base, d1,d2>, base>::value,"type does not exist"); const auto main ( ) noexcept(true) -> decltype(0xC0DE) {}
It seems to me that the order of args to common_type affects the results of the metafunction. Is this intentional,unintentional or is it due to my lack of understanding?
— Preceding unsigned comment added by Seet82 (talk • contribs) 8 September 2024
MediaWiki formatting was applied by --Space Mission (talk) 16:11, 8 September 2024 (PDT).
- It matches how the ternary expression works/fails, I believe it is intentional. I.e. std::common_type_t<base, d1, d2> works and so does false ? false ? base() : d1() : d2(); std::common_type_t<d1, d2, base> fails and so does false ? false ? d1() : d2() : base() --Ybab321 (talk) 06:42, 8 September 2024 (PDT)
[edit] typo
typo "_Static_assert ( expression ) (since C23)(deprecated in C23)"
Should be
"_Static_assert ( expression ) (since C11)(deprecated in C23)"
Mszajner (talk) 02:13, 10 September 2024 (PDT)
- That one is correct, the form without the message is new in C23 ✘ Not done --Ybab321 (talk) 02:38, 10 September 2024 (PDT)
[edit] bitset operator ordering
https://en.cppreference.com/w/cpp/utility/bitset links to a page about operators <<=, >>=, << and >>.
https://en.cppreference.com/w/cpp/utility/bitset/operator_ltltgtgt orders them << <<= >> >>=.
I have no opinion on which order is better, but inconsistent order definitely isn't the better option.
(I'm also unsure why <<, >> and ~ are in the modifiers section. They are similar to the actual modifier operators, and splitting them would probably cause more trouble than it solves; maybe rename that section to bulk operations or something?)
--98.128.166.54 15:25, 14 September 2024 (PDT)
[edit] Error on std::ignore page
Hi! There is an error on [the page https://en.cppreference.com/w/cpp/utility/tuple/ignore], as by standard there can be no definition of std::ignore in <utility>, only in <tuple> (in C++20 standard it is section 20.5 of <tuple> that defines std::ignore, there is no mentions about it in sections 20.2-20.4 of <utility>). --Melirius 31.183.158.11 02:10, 16 September 2024 (PDT)
- It's over here, DR'd back to C++11 from P2968 --Ybab321 (talk) 03:09, 16 September 2024 (PDT)
- But it is not yet in standard, so that current page state is misleading, and code with std::ignore does not compile with <utility> on GCC. --Melirius 31.183.158.11 05:31, 17 September 2024 (PDT)
- It is in the standard (per the link I provided). Perhaps one of the DR astute editors could weigh in on the legitimacy of this retroactive application? --Ybab321 (talk) 10:52, 17 September 2024 (PDT)
- OK, can it be at least stated that it is "Defined in header <utility>" from C++26? --Melirius 31.183.158.11 06:48, 18 September 2024 (PDT)
- Nope. It will be available (i.e. back-ported via DR11) to C++11 mode, as you may see on C++26 compiler support page searching for std::ignore or
P2968R2
(it is end - 1 tables line). --Space Mission (talk) 07:26, 18 September 2024 (PDT)- Ah, OK, thanks for clarification. --Melirius 31.183.129.121 11:55, 28 September 2024 (PDT)
- Nope. It will be available (i.e. back-ported via DR11) to C++11 mode, as you may see on C++26 compiler support page searching for std::ignore or
- OK, can it be at least stated that it is "Defined in header <utility>" from C++26? --Melirius 31.183.158.11 06:48, 18 September 2024 (PDT)
- It is in the standard (per the link I provided). Perhaps one of the DR astute editors could weigh in on the legitimacy of this retroactive application? --Ybab321 (talk) 10:52, 17 September 2024 (PDT)
- But it is not yet in standard, so that current page state is misleading, and code with std::ignore does not compile with <utility> on GCC. --Melirius 31.183.158.11 05:31, 17 September 2024 (PDT)
[edit] Change example code for Scalar initialization
The example code for scalar initialization still includes "stdbool.h", which is no longer necessary due to changes made in c23.
[edit] Example
int main(void) { bool b = true; const double d = 3.14; int k = 3.15; // conversion from double to int int n = {12}, // optional braces *p = &n, // non-constant expression OK for automatic variable (*fp)(void) = main; enum {RED, BLUE} e = RED; // enumerations are scalar types as well }
- I wouldn't mind seeing the
stdbool.h
includes removed, but there's gonna be quite a few examples on the site that include that header. Considering there's no harm and it provides pre-C23 compatibility, I don't think it makes sense to spend the effort removing these includes, other than in-passing. --Ybab321 (talk) 03:21, 16 September 2024 (PDT)
[edit] type for pack fold expression with comma operator and empty pack
The page https://en.cppreference.com/w/cpp/language/fold currently indicates the type is "void()", but I guess it should be simply "void".
- The type is void, but the value is void(), which may look weird, but it's a valid expression (e.g. one can define a function decltype(void()) f() {} or instantiate std::less<decltype(void())>) --Ybab321 (talk) 02:44, 18 September 2024 (PDT)
[edit] Enabling list initialization for algorithms
Hi,
GCC 15 will have support for P2248 + P3217 (C++26), https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=dc47add79261679747302293e1a5e49ba96276b1 just got merged. I can't edit the corresponding page: https://en.cppreference.com/w/cpp/compiler_support/26#C.2B.2B26_library_features
Peppe (talk) 11:30, 22 September 2024 (PDT)
- ✔ Done in this diff. Thanks. --Space Mission (talk) 11:52, 22 September 2024 (PDT)
- BTW, if you are interested, the std::erase(std::inplace_vector(c), {init-list}) function template also should have a default parameter similar to what was proposed in P2248/P3217. Apparently this hasn't been done yet, since std::inplace_vector has only recently been approved for C++26 and hence the author of P2248 (Giuseppe D'Angelo) has not covered this container unlike others:
- --Space Mission (talk) 13:51, 22 September 2024 (PDT)
- Hi, that's me, author of P2248 and author of the GCC patch above :-) std::erase for inplace_vector has already a defaulted template argument (enabling list initialization) as far as I can see: https://eel.is/c++draft/inplace.vector.erasure (was also in the paper https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p0843r14.html#containerssequencesinplacevectorerasure-Erasure ). The lack of =T in the synopsis was a typo in the draft: https://github.com/cplusplus/draft/commit/be25cad , maybe that's what caused the confusion on the page here on the wiki?
- Ah, most likely. This is all funny. :) And U = T here is fixed too. --Space Mission (talk) 17:30, 22 September 2024 (PDT)
[edit] Qualified name lookup page error in first line
Qualified name lookup This is its link https://en.cppreference.com/w/cpp/language/qualified_lookup.
The first line said "A qualified name is a name that appears on the right hand side of the scope resolution operator :: (see also qualified identifiers).".
It points out the right of the '::' is the qualified name, however, it's obviously wrong.
It should be correct to "the left of the '::'.
For example, in `std::cout`, the 'cout' is the qualified name.
[edit] Request to update hyperlinks and synchronize other languages
MediaWiki:Autolinker-definition-c and MediaWiki:Autolinker-definition-cpp have not been updated for over 3 years and other languages have not been synchronized with English. It seems to have caused some hyperlinks to break, such as ranges::data
on the contiguous_range (zh).--YexuanXiao (talk) 14:26, 23 September 2024 (PDT)
- 請稍等。更新 的 GenSHin JSON 應該在我的待辦事項清單中。--Space Mission (talk) 15:27, 23 September 2024 (PDT)
[edit] Typo in The rule of three/five/zero
In the rule of of five section, the move assignment operator definition is missing a `return *this;`.
- ✔ Done. Good catch. The return *this was just added with this diff.) --Space Mission (talk) 16:27, 24 September 2024 (PDT)
[edit] Minor spelling mistake
|- class="t-par" | lock | - | an lock which must be locked by the calling thread
in https://en.cppreference.com/w/cpp/thread/condition_variable/wait_for should be:
|- class="t-par" | lock | - | a lock which must be locked by the calling thread
Definition `std::tuple_element_t` is missed.
- It's here: std::tuple_element_t or, more precisely, in this section: std::tuple_element_t. --Space Mission (talk) 03:12, 28 September 2024 (PDT)
[edit] cpp/utility/to chars example bug
Hello in the example code, the fallback to C++17 has a bug in the std::string_view constructor as it currently uses a C++20 constructor. It should use the pointer and size constructor instead. I have copied the correct code below. Nvasilas (talk) 00:02, 29 September 2024 (PDT) Nikos Vasilas
#include <array> #include <charconv> #include <iostream> #include <string_view> #include <system_error> void show_to_chars(auto... format_args) { std::array<char, 10> str; #if __cpp_lib_to_chars >= 202306L and __cpp_structured_bindings >= 202406L // use C++26 structured bindings declaration as condition (P0963) // and C++26 to_chars_result::operator bool() for error checking (P2497) if (auto [ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), format_args...)) std::cout << std::string_view(str.data(), ptr) << '\n'; else std::cout << std::make_error_code(ec).message() << '\n'; #elif __cpp_lib_to_chars >= 202306L // use C++26 to_chars_result::operator bool() for error checking (P2497) if (auto result = std::to_chars(str.data(), str.data() + str.size(), format_args...)) std::cout << std::string_view(str.data(), result.ptr) << '\n'; else std::cout << std::make_error_code(result.ec).message() << '\n'; #else // fallback to C++17 if-with-initializer and structured bindings if (auto [ptr, ec] = std::to_chars(str.data(), str.data() + str.size(), format_args...); ec == std::errc()) std::cout << std::string_view(str.data(), ptr - str.data()) << '\n'; else std::cout << std::make_error_code(ec).message() << '\n'; #endif } int main() { show_to_chars(42); show_to_chars(+3.14159F); show_to_chars(-3.14159, std::chars_format::fixed); show_to_chars(-3.14159, std::chars_format::scientific, 3); show_to_chars(3.1415926535, std::chars_format::fixed, 10); }
Possible output:
42 3.14159 -3.14159 -3.142e+00 Value too large for defined data type
- That example code isn't actually intending to be C++17 compatible (it's in an abbreviated function template after all), it's merely referring to the if-with-initialiser language feature introduced in C++17. I'll add the change in anyway though for the std::to_chars_results page; for the main std::to_chars page, I think that's far too much for a basic usage example, so I've reduced it down to a reasonable version that will always work. ✔ Done --Ybab321 (talk) 08:24, 29 September 2024 (PDT)
[edit] Bad explaination in https://en.cppreference.com/w/cpp/thread/future/~future
The page as of now returns to the book "Effective Modern C++ Item 36". However, that specific item does not address what happens during the destruction of a future object but a std::thread object. The destruction of futures is discussed in item 38 instead. More importantly, it does not seem like good practice to refer to a commercial non-free book, instead of keeping the explanation self-contained.
I propose something more along the lines of
- If the std::async task is launched with:
- std::launch::async: This guarantees that the task is run asynchronously in a separate thread. Destroying the std::future without calling get() or wait() does not terminate the thread. The task will still run in the background, but the result of the task will be discarded. The destructor of std::future does not wait for the task to complete unless you explicitly call get() or wait().
- std::launch::deferred: The task is deferred and only executed when get() or wait() is called. If the std::future object is destroyed before either of these functions is invoked, the task is never executed, and the destructor just discards the future without running the task.
- The questionable explanation is now removed.✔ Done --Xmcgcg (talk) 18:41, 29 September 2024 (PDT)
- you're mostly describing async policies, which are on their own page, cpp/thread/async. As for ~future, the relevant bit of standardese is https://eel.is/c++draft/futures.state#5.3 which came from wg21.link/n3776 after several years of tense arguments leading to carving this awkward special case for futures obtained from std::async (personally I preferred the paper that gave that future a distinct type, std::waiting_future). Anyway, agree the comment wasn't great, but I see it's already changed while I was writing this --Cubbi (talk) 18:44, 29 September 2024 (PDT)
[edit] const and mutable are wrong
The function
// Multiple threads/readers can read the counter's value at the same time. unsigned int get() const { std::shared_lock lock(mutex_); return value_; }
Is declared as const but the mutable makes it not a const. It does an action which a const should not
mutable std::shared_mutex mutex_;
Whatever the reason for using mutable this is not a good one.
[edit] Add noexcept to declarations
Since it is 2024, I suggest to change all occurrences of "(noexcept since c++11)" into "(no noexcept before c++11)" and add the noexcept to the declaration.
For example, change
const_iterator end() const; (noexcept since c++11)
into
const_iterator end() const noexcept; (no 'noexcept' before c++11)
CarloWood (talk) 03:12, 30 September 2024 (PDT)
- Eh, noexcept isn't really an important part of the signature, and the overall result seems a bit harder to read to me. We do need to tackle the issue of noexcept and constexpr not being added to signatures in the non-diff view though --Ybab321 (talk) 07:53, 1 October 2024 (PDT)
[edit] strstr example discards const
The example on strstr discards const (twice).
The char *str = "..."; in main should be const
or char str[] = "...";
And char *pos = strstr(str, substr); is certainly missing const
. Compilers don't warn about this one yet, so it's still a potential landmine. The rest of the pages for the search functions that are now generic in c23 seem fine.
Torsten.dev (talk) 13:15, 30 September 2024 (PDT)
- Added the missing consts, thanks. They're technically not needed, but clearly they should be there. ✔ Done --Ybab321 (talk) 02:43, 1 October 2024 (PDT)
- Not sure I fully agree here: that's a C page and string literals are non-const arrays of char there even if non-modifiable; compilers have nothing to warn about. I suppose our examples could constify pointers to them as good practice, dunno if C ppl get offended as they do by the casts from void*... --Cubbi (talk) 11:56, 3 October 2024 (PDT)
- The change in main was just a defensive best practise, yes. I doubt this usage will be marked obscolecent in my lifetime, though it arguably should, so it's a hazard compilers can't warn about. Imho it's something we should no longer be teaching.
- The thing compilers might complain about in the future was the use of strstr in the find_str function. Since c23 it now auto-magically returns the same qualifiers as the first argument, which here is const. The change in c23 was specifically introduced for future compilers to warn for this case. So assumedly compilers will warn about it in the future. --Torsten.dev (talk) 16:04, 4 October 2024 (PDT)
[edit] std::print example section overloads incorrect
https://en.cppreference.com/w/cpp/io/print
Locked for me.
The overloads changed order in a revision on 26 April 2024. Comments in the example were not updated accordingly.
Change this to overload (1).
std::print("{0} {2}{1}!\n", "Hello", 23, "C++"); // overload (2)
Change this to overload (2).
std::print(stream, "File: {}", tmp.string()); // overload (1)
The-lambda-way (talk) 18:04, 30 September 2024 (PDT)
[edit] C time
https://en.cppreference.com/w/c/chrono
View Mode: Diff/C89/etc..
strftime Defined in header wchar.h
wcsftime Defined in header time.h
That's definitely an error, time.h and wchar.h should be swapped.
- You're reading backwards. strftime is in the section of functions defined in <time.h>, wcsftime is in the section of functions defined in <wchar.h> --Ybab321 (talk) 07:04, 1 October 2024 (PDT)
[edit] Update example, std::tuple_element<tuple>
https://en.cppreference.com/w/cpp/utility/tuple/tuple_element
Here's an updated version of hte example showing how cv-qualification and references are preserved. Also, PrintTypeAtIndex has been modified to better handle some compilers' wonky implementation of typeid.
Mapwiz 07:43, 1 October 2024 (PDT)
#include <cstddef> #include <iostream> #include <string> #include <tuple> #include <typeinfo> #include <type_traits> #include <utility> namespace details { template<class TupleLike, std::size_t I> void printTypeAtIndex() { std::cout << " The type at index " << I << " is: "; using SelectedType = std::tuple_element_t<I, TupleLike>; std::cout << typeid(std::remove_cv_t<std::remove_reference_t<SelectedType>>).name(); if constexpr (std::is_const_v<std::remove_reference_t<SelectedType>>) std::cout << " const"; if constexpr (std::is_volatile_v<std::remove_reference_t<SelectedType>>) std::cout << " volatile"; if constexpr (std::is_lvalue_reference_v<SelectedType>) std::cout << "&"; if constexpr (std::is_rvalue_reference_v<SelectedType>) std::cout << "&&"; std::cout << '\n'; } } template<typename TupleLike, std::size_t I = 0> void printTypes() { if constexpr (I == 0) std::cout << typeid(TupleLike).name() << '\n'; if constexpr (I < std::tuple_size_v<TupleLike>) { details::printTypeAtIndex<TupleLike, I>(); printTypes<TupleLike, I + 1>(); } } struct MyStruct {}; using MyTuple = std::tuple<int, long &, char const &, bool&&, std::string, volatile MyStruct>; using MyPair = std::pair<char, bool&&>; static_assert ( std::is_same_v<std::tuple_element_t<0, MyPair>, char> && std::is_same_v<std::tuple_element_t<1, MyPair>, bool&&> ); int main() { printTypes<MyTuple>(); printTypes<MyPair>(); }
Possible output:
output (gcc, godbolt): You may need to sanitize this. St5tupleIJiRlRKcObNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEV8MyStructEE The type at index 0 is: i The type at index 1 is: l& The type at index 2 is: c const& The type at index 3 is: b&& The type at index 4 is: NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE The type at index 5 is: 8MyStruct volatile St4pairIcbE The type at index 0 is: c The type at index 1 is: b&& MSVC output class std::tuple<int,long & __ptr64,char const & __ptr64,bool && __ptr64,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct MyStruct volatile > The type at index 0 is: int The type at index 1 is: long& The type at index 2 is: char const& The type at index 3 is: bool&& The type at index 4 is: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > The type at index 5 is: struct MyStruct volatile struct std::pair<char,bool && __ptr64> The type at index 0 is: char The type at index 1 is: bool&&
Mapwiz 07:43, 1 October 2024 (PDT)
A few MediaWiki's formatting tags were applied by --Space Mission (talk) 15:56, 3 October 2024 (PDT)
- ✔ Done. The example was updated. Thanks.) --Space Mission (talk) 15:56, 3 October 2024 (PDT)
The discussion of ranking implicit conversion sequences: [16] Does not make sense, because it lists what it calls "standard conversion sequences" that might include "user-defined conversion[s]". A standard conversion sequence may not include any user-defined conversions (though an implicit conversion sequence might include a user-defined conversion).
So possibly the page reads "standard conversion sequence" where it should read "implicit conversion sequence," but even changing that does not make sense, because does rank apply to all conversions, or just standard conversions? In particular, the rank language implies that there are user-defined conversions of rank 1 and standard conversions of rank 3. Is that the intended meaning? In that case, maybe clearer to introduce rank after the higher-priority rule that a standard conversion sequence is always better than a user-defined conversion regardless of rank, or at least to put a forward reference that rank becomes relevant only in rule 3?
Wikweb (talk) 17:34, 4 October 2024 (PDT)
[edit] Typing error
In this page https://en.cppreference.com/w/c/string/byte there is a table with a little typing error. The second last line of the table states: 123–126 \x7B–\x7E \172–\176 {|}~, that are the values of the decimal, hexadecimal and octal notation for ASCII characters. But 123 is \173, and not \172. I'm a new user and so I cannot edit it by myself. Hope someone could fix it, thanks in advance to anyone who can fix it, have a nice day, Simone SimoAiello (talk) 21:23, 6 October 2024 (PDT)
- ✔ Done Wow, you are correct! And it's been fixed. --Space Mission (talk) 11:21, 7 October 2024 (PDT)
[edit] Broken link in https://en.cppreference.com/w/c/language/behavior
External link #4(Undefined behavior can result in time travel (among other things, but time travel is the funkiest)) is moved to https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633
✔ Done This funky link's been updated. Thanks!) --Space Mission (talk) 11:29, 7 October 2024 (PDT)
[edit] Bug in https://en.cppreference.com/w/cpp/algorithm/ranges/transform possible implementation?
Hi,
The GCC implementation does `std::move` on `first1` and `result` upon returning in the first variant, and the equivalent in the others. I believe it's correct. Without that I believe the return statement will often not compile.
Best regards,
Alain Mosnier
- Fixed (by Space Mission) ✔ Done.
- Here's how I would have written it if I had my way :) https://godbolt.org/z/KMThx5eG4 --Ybab321 (talk) 03:18, 8 October 2024 (PDT)
[edit]
At this page: [17]
(5) and (7) state that these ops are equivalent to p->swap(r) but that is not true. Please, fix.
- Not sure why you think that's not true. Function (5) is specified here and function (7) here --Ybab321 (talk) 03:25, 8 October 2024 (PDT)
- Yesterday I've replaced "equivalent to" with "as if by" which is obviously a more conceptual yet less stringent requirement. It's noteworthy that the History of the page contains the [SO link] that also sheds light on the topic.) ✔ Done --Space Mission (talk) 06:06, 8 October 2024 (PDT)
[edit] updating printf/scanf for c23
I would like to see printf_format updated according to N2680 and N2630, corresponding C++ docs TBD.
This would include adding a row in the table for b as well as adding a collumn for %wN and %wfN
(intN_t
/ int_leastN_t
(C23) and int_fastN
_t(C23) respectively).
I'd love for the rows and columns to be hidden on older revisions. Is it possible to define templates on user pages to test some designs for this?
I'm unsure how we should describe B since it is (optional) in a different way than the rest of the page is using that. Is it (conditionally present) if it exists if and only if PRIBN and friends exist?
We could add a possible implementation section to integer to show the equivalence between c23 %wN specifiers and the PRI/SCI macros. I hate those macros, I want people to see the future has options.
Some smaller changes you can pick up directly:
On strtol,strtoul,strtoimax, and wcstol,wcstoul,wcstoimax pages add -> optional "prefix (0b or 0B) indicating binary (applies only when the base is 2 or 0) (since C23)
--Torsten.dev (talk) 19:41, 7 October 2024 (PDT)
- Hm, doesn't look like the easiest thing to specify in that table. Tbh, I've never really liked that table much, most of the columns are exclusively for integers, I think it would benefit from breaking out the integers into their own section, and perhaps the floating points also. If integers have their own section, it should make it easier to talk about these new formatter specifiers that aren't just simple well-known letters and have conditional presence. Adding the ability to hide part of the table in old revisions is certainly technically possible, but to be blunt, there's practically no chance anyone will write the functionality for it.
- Also, neat, I had no idea they added the binary specifier! --Ybab321 (talk) 13:08, 8 October 2024 (PDT)
- Here is a draft of my idea. Having seen how complex floating point formatting is, I'm more inclined to think this is the way to go. The revboxes and the ability to write notes pertaining to multiple format specifiers more locally to where those specifiers are described are nice bonuses --Ybab321 (talk) 05:11, 11 October 2024 (PDT)
- I like the section on floating point numbers. I'm a bit more torn on the integer section. I think I would miss a table like:
Length Modifier Signed Unsigned hh
(since C99)signed char unsigned char h
short unsigned short (none) int unsigned int l
long unsigned long ll
(since C99)long long unsigned long long j
(since C99)intmax_t uintmax_t z
(since C99)signed size_t size_t t
(since C99)ptrdiff_t unsigned ptrdiff_t wN
(since C23)intN_t
int_leastN_t
uintN_t
uint_leastN_t
wfN
(since C23)int_fast N
_tuint_fast N
_t
- too much in its current state, because it's so much easier to go from type to specifier and vice versa.
- It's a shame that the tables interact with revs so badly, perhaps if you separate unsigned and signed more idk? --Torsten.dev (talk) 03:34, 15 October 2024 (PDT)
- The table as proposed is definitely appealing, I could swing either way on that. I will point out though that
int_leastN_t
can't necessarily usewN
(e.g. if CHAR_BIT = 16, then int_least8_t is 16 bits and hence not compatible withw8
). Meanwhile, other types can matchwN
, e.g.w64
can be used with long and long long on LP64. So it'll have to be my current wording that goes into the table for that row unfortunately. --Ybab321 (talk) 05:20, 15 October 2024 (PDT)
- The table as proposed is definitely appealing, I could swing either way on that. I will point out though that
- It should always work.
- § 7.22.1.2, Minimum-width integer types 3)
- If the typedef name
intN_t
is defined,int_leastN_t
designates the same type. If the typedef nameuintN_t
is defined,uint_leastN_t
designates the same type.
- If the typedef name
- and § 7.23.6.1 the fprintf function 7)
- wN ... All minimum-width integer types (7.22.1.2) and exact-width integer types (7.22.1.1) defined in the header <stdint.h> shall be supported. Other supported values of N are implementation-defined.
- The [u]int_leastN_t types for N=8,16,32,64 are required.
- The w8,w16,w32,w64 the length specifiers specify the [u]int_leastN_t types,
- if the [u]intN_t types exist, it will work for them too since they designate the same type.
- --Torsten.dev (talk) 11:17, 17 October 2024 (PDT)
It doesn't work for the example I described. int8_t
won't be defined, so int_least8_t
isn't an 8-bit type, it will be 16 bits, hence w16
will be a required length specifier (as support for int_least8_t
is required), and w16
should be used for int_least8_t
(as that's the width of the integer) in that datatype model. The wN
length specifier only always works for [u]intN_t
(and may work for other types). --Ybab321 (talk) 07:54, 18 October 2024 (PDT)
- It should. Check the C23 and N2680 language. What you propose is more in line with N2511 which is a previous version of the proposal.
- Check also the Rational in $ 2. Suggested changes:
- This proposal requires that on implementations that define the typedef name
[u]intN_t
,[u]int_leastN_t
must designate the same type. This constrains these types in a manner that allows the specific width length modifierwN
to be used for both minimum-width integer types (7.20.1.2) and exact-width integer types (7.20.1.1).
- This proposal requires that on implementations that define the typedef name
- Insofar as the final language in the standard allows for your interpretation it is my opinion that such language would be a defect.
- w8 should mean it stores the promoted type in a
[u]int_least8_t
which is exactly 8 bit if and only if [u]int8_t is defined too. Otherwise it's however many bits wide as it needs to be. The removal of "exact width" and reference to N bits also suggests to me that was the intent, but this may be worthy of a clarification request. - --Torsten.dev (talk) 06:08, 22 October 2024 (PDT)
- N2680 has been my reference heretofore. The rationale you quoted is predicated on implementations that define
intN_t
, for an implementation that has 16-bitint_least8_t
this doesn't apply. Let's consider the%n
format specifier, as it's a bit more clear cut. Quoting N2680: - >
wN
Specifies that [...] a followingn
conversion specifier applies to a pointer to an integer type argument with a width of N bits. - If
int_least8_t
is 16 bits, then a pointer to aint_least8_t
is not a pointer to an integer type argument with a width of 8 bits, so it cannot be used withw8
. --Ybab321 (talk) 07:27, 22 October 2024 (PDT)
- N2680 has been my reference heretofore. The rationale you quoted is predicated on implementations that define
@Ybab321 You made a valid point,
- integer type argument with a width of N bits.
Sounds like it could mean, exactly N bits.
However note § 7.22.1.1 Exact-width integer types:
- integer type with width N and no padding bits
and §7.22.1.2 Minimum-width integer types
- integer type with a width of at least N
(emph mine)
The language of "at least", "exact" or "and no padding" is notably absent.
To make sure I wasn't reading to much into this absence however, I emailed Robert C. Seacord to make sure:
- Yes wN is for all minimum-width integer types (7.20.1.2) and exact-width integer types (7.20.1.1) with a width of N bits (regardless of the actual sizes).
- ...
- For example, w8 can be used with
[u]int_least8_t
. - The following additional change to the standard makes this work:
- If the typedef name intN_t is defined, int_leastN_t designates the same type.
- If the typedef name uintN_t is defined, uint_leastN_t designates the same type.
- -- rCs (by email)
Hope that settles it. And big kudos to rCs. --Torsten.dev (talk) 11:38, 30 October 2024 (PDT)
- Ah, an integer width refers specifically to the non-padding bits (6.2.6.2). Robert is right that
wN
is for all minimum-width integer types with a width of N. Unfortunately, the width ofint_leastN_t
is not specified to be N, merely it's given a minimum of N by 7.22.2.2. So that meansint_leastN_t
may only be used withw8
ifINT_LEAST8_WIDTH
happens to be exactly 8. - In any case, these new format specifiers will be potentially compatible with other integer types than the fixed and minimum width integer type aliases, so I see no reason to tie down the description of permitted arguments to just the type aliases anyway. --Ybab321 (talk) 13:16, 30 October 2024 (PDT)
[edit] or_eq typo
or_eq should say it is the alternative for |=, not !=.
- Sigh, right.) ✔ Fixed. --Space Mission (talk) 18:28, 8 October 2024 (PDT)
[edit] missing code for primary template in https://en.cppreference.com/w/cpp/language/parameter_pack
I guess that, for friend declarations in C++26, you should add this code on top, to define the primary template:
template<class... Ts>
class R
{
friend Ts;
};
Mauro russo (talk) 01:26, 9 October 2024 (PDT)Mauro Russo
[edit] The input_range page should mention that begin() should be called at most once
This is quite important to know when writing a generic algorithm that should support input_range.
See [range.range] section in the C++20 latest working draft:
(3.3) if the type of ranges::begin(t) models forward_iterator, ranges::begin(t) is equality-preserving.
(4) [ Note: Equality preservation of both ranges::begin and ranges::end enables passing a range whose iterator type models forward_iterator to multiple algorithms and making multiple passes over the range by repeated calls to ranges::begin and ranges::end. Since ranges::begin is not required to be equality-preserving when the return type does not model forward_iterator, repeated calls might not return equal values or might not be well-defined; ranges::begin should be called at most once for such a range. — end note ]
[edit] refine a phrasing in https://en.cppreference.com/w/cpp/language/if
I guess that the following:
If the else part of the if statement is present and statement-true is also an if statement, ... (in other words, ... the else is associated with the closest if that does not have an else).
might be better stated as:
If the else part of the if statement is present and statement-true is also an if statement, ... (in other words, ... the else is associated with the closest if that does not have YET an ASSOCIATED else).
In practice, I suggest to elaborate with 'yet' and 'associated'.
- No fix is required.✘ No change When you reach the an else, you already know whether an if preceding it has an else. --Xmcgcg (talk) 02:30, 14 October 2024 (PDT)
- I like the rephrasing. ✔ Done --D41D8CD98F (talk) 09:40, 18 October 2024 (PDT)
[edit] Error in ranges::push_heap() and ranges::pop_heap()
Error on https://en.cppreference.com/w/cpp/algorithm/ranges/pop_heap and https://en.cppreference.com/w/cpp/algorithm/ranges/push_heap
In the section "Parameters", "pred" is listed, but instead it should mention "comp - comparison to apply to the projected elements"
Blueberry (talk) 06:42, 13 October 2024 (PDT)
- Fixed.✔ Done Other heap operations will be updated later. --Xmcgcg (talk) 02:30, 14 October 2024 (PDT)
[edit] size doesn't work for forward_list
In https://en.cppreference.com/w/cpp/header/forward_list, it shows size (C++17) ssize (C++20) works for forward_list, while neither std::size(a_forward_list) nor a_forward_list.size() compiles for g++ -std=c++17
- std::forward_list does indeed not support
size()
, it's rather strange that those operations are included in the <forward_list> header, but that's what the standard prescribes --Ybab321 (talk) 03:08, 14 October 2024 (PDT)
[edit] C atomic_thread_fence is misleading/wrong
In https://en.cppreference.com/w/c/atomic/atomic_thread_fence it says atomic_thread_fence "Establishes memory synchronization ordering of non-atomic and relaxed atomic accesses, as instructed by order, without an associated atomic operation". But in n2310 7.17.4, all fence synchronizations require an atomic object and some atomic operations. --Fzl (talk) 18:28, 13 October 2024 (PDT)
- it is indeed an incomplete description (its point was to highlight the diff from syncronizations on specific atomic ops, like CAS); the C++ equivalent does a better job at describing the operation and we should probably copy/edit it over. --Cubbi (talk) 09:03, 15 October 2024 (PDT)
[edit] Add two C++ libraries in open-source page
I want to add two C++ library in "A list of open-source C++ libraries" page.
Frist:
[edit] Communication
! FPNN | Fast Programmable Nexus Network. High performance fully asynchronous RPC service framework. Simultaneously supporting HTTP, WebSocket, TCP, and reliable UDP. Support the development of ultra-high voltage servers, with corresponding language client SDKs. | | make |-
Second:
[edit] JSON
! swxJson | The most convenient C++JSON library currently in use. Read and write complex structures at any level with just one function call. The performance is approximately half that of RapidJSON. | MIT | make |-
You can find them at https://github.com/highras/fpnn and https://github.com/swxlion/swxjson.
These libraries are developed and used in www.FunPlus.com & www.centurygames.com in their infrastructure such as Intercontinental real-time signaling&messaging system from 2015 to present.
So I hope you can check, verify and add them.
Thanks.
- ✔ Done These libs were added, as you can see:FPNN & wsxJson.) --Space Mission (talk) 15:16, 25 October 2024 (PDT)
[edit] Description of cases with no minimum is not correct
Ian:
I think this line: "that is, types that represent an infinite set of negative values have no meaningful minimum." should be changed as it's not strictly correct.
We can imagine a floating point type that has a big unsigned int with infinite precision which is used to represent only negative exponents but only a finite precision mantissa, let's say no mantissa for simplicity.
That would represent an infinite number of values between -2.0 and 2.0, all of the form +/- 2^(-n). So there would be a meaningful minimum even though there are an infinite number of negative values.
This type is not unreasonable to think of, as it can be useful for representing values between -1 and 1 where the scale of the value is more important than the local precision. So you could use it to represent normalized magnitudes where -1 is the minimum value in some dataset and 1 is the maximum.
- ✔ Done that sentence in cpp/types/numeric_limits/min was trying to rephrase https://eel.is/c++draft/numeric.limits.members#4 but I agree the "that is, .." doesn't help. --Cubbi (talk) 11:04, 17 October 2024 (PDT)
[edit] grammar fix
"A variable satisfying all following conditions have"
should be "has"
in cpp/language/storage duration
2A00:79E0:D:209:D95E:F627:8B11:6483 07:40, 16 October 2024 (PDT)
✔ Fixed @ Static storage duration. --Space Mission (talk) 16:57, 21 October 2024 (PDT)
[edit] std::mdspan::extent(rank_type i) member function seems to be missing
This member function is used in the example at the bottom but is missing from the list of member functions.
- ✔ Done added. --D41D8CD98F (talk) 10:43, 18 October 2024 (PDT)
[edit] Common.js should be synchronized to other languages
https://en.cppreference.com/mwiki/index.php?title=MediaWiki:Common.js
[edit] Uniform init instead of copy assignment
Hya, just to emphasize best practices, wouldnt it be preffereable to use uniform init in the first example:
--`int a[2] = {1, 2};`
++`int a[2] {1, 2};`
Cheers Heck
- It doesn't really matter, but if there was a best practice, it would be to use copy-init or copy-list-init whenever explicit conversion isn't intended, then the compiler can rescue you if you mistakenly pass an argument that requires explicit conversion. --Ybab321 (talk) 03:46, 21 October 2024 (PDT)
[edit] Incorrectly rendered class declaration in cpp/chrono/month_weekday
Hi,
Class declaration in cpp/chrono/month_weekday contains an error / typo and doesn't render correctly.
Currently it's written as {{ddcl|header|chrono|...}}
, but it should be {{ddcl|header=chrono|...}}
.
[edit] Missing link to regular_invocable in std Symbol Index
std::regular_invocable
is missing from cpp/symbol_index.
It was (probably accidentally) replaced with invocable
in this version and later removed as a duplicate.
Can someone add std::regular_invocable
to the index, please?
2A02:6B8:B081:8017:0:0:1:2E 13:08, 24 October 2024 (PDT)
- ✔ Done: added to cpp/symbol index#R. Thanks.) --Space Mission (talk) 16:31, 25 October 2024 (PDT)
[edit] Missing link to header in cpp/atomic/atomic_wait
Hi,
The page for std::atomic_wait is missing a link to <atomic> header. It was lost in the last edit. Can someone restore it please?
Mystaravinthor (talk) 01:10, 25 October 2024 (PDT)
[edit] Unnecessarily mutable lambda in std::ranges::generate
We currently have this snippet:
void iota(auto& v, int n) { std::ranges::generate(v, [&n]() mutable { return n++; }); }
The mutable should be removed here because it does nothing. It would only be necessary if n was captured by copy.
Also why can't I edit that page? My account has first made edits in 2021 :(
- Yea, ✔ fixed: the example for std::ranges::generate() has been updated.
- As for editorial policies, they needed to be tightened in response to some recent massive acts of nonconstructive behavior.) --Space Mission (talk) 15:16, 25 October 2024 (PDT)
[edit] Incorrect header for std::filebuf / std::wfilebuf
cpp/io/basic_filebuf says these aliases are defined in <streambuf>
, but according to [lib.fstreams], they are defined in <fstream>
.
Mystaravinthor (talk) 12:00, 25 October 2024 (PDT)
- ✔ Fixed @ std::basic_filebuf. Thanks.) --Space Mission (talk) 15:57, 25 October 2024 (PDT)
[edit] Removing outdated type requirements
The `std::inner_product` [page](https://en.cppreference.com/mwiki/index.php?title=cpp/algorithm/inner_product&type=signup) mentions `ForwardIt1` and `ForwardIt2` in the "Type requirements" section, but those types were removed some time ago.
[edit] Explanation of convertible_to
The std::convertible_to
page lacks an explanation of why std::convertible_to differs from std::is_convertible. A good example is located at https://stackoverflow.com/a/62644127/12828940. --ddvamp (talk)
- ✘ No Fix Required The definition of std::convertible_to already shows that std::convertible_to<From, To> subsumes std::is_convertible_v<From, To>. --Xmcgcg (talk) 18:19, 27 October 2024 (PDT)
- Perhaps I expressed myself incorrectly. The point is not in the definition, but in the fact that entry- and middle-level programmers may not know that there are cases where an implicit conversion is possible, but an explicit conversion is ill-formed, which is rather unobvious. I meant to add an example showing that using std::convertible_to and std::is_convertible may not be equivalent. --ddvamp (talk) 04:09, 31 October 2024 (PDT)
- There's quite a lot of sanity constraints in the stdlib templates that I don't know if we should elaborate on, or if that elaboration would introduce needless confusion. In this particular case, it's such a pathogenic type required for demonstration that I don't think anyone cares other than C++ theoreticians. I'd be willing to add a link to the stack overflow page at least. --Ybab321 (talk) 05:46, 31 October 2024 (PDT)
- Perhaps I expressed myself incorrectly. The point is not in the definition, but in the fact that entry- and middle-level programmers may not know that there are cases where an implicit conversion is possible, but an explicit conversion is ill-formed, which is rather unobvious. I meant to add an example showing that using std::convertible_to and std::is_convertible may not be equivalent. --ddvamp (talk) 04:09, 31 October 2024 (PDT)
[edit] std::inplace_vector constructor signatures fix
The std::inplace_vector::inplace_vector(size_type) and std::inplace_vector::inplace_vector(size_type, const T&) have a bug in their signatures.(https://en.cppreference.com/w/cpp/container/inplace_vector/inplace_vector).
The signatures on the site are as follows: constexpr explicit inplace_vector( std::size_type count ); and constexpr inplace_vector( std::size_type count, const T& value );
The std:: part before the count parameter should be erased.
Correct signatures would look like: constexpr explicit inplace_vector( size_type count ); and constexpr inplace_vector( size_type count, const T& value );
Cpiernikowski (talk) 14:48, 29 October 2024 (PDT)
[edit] std::map<K, V>::insert() overload notes inconsistency
The page on std::map<K, V>::insert() mentions explicitly for the 10th overload the element is moved into the container. This explicit mention of moving the element is not made for the 9th overload, even though it also uses move semantics. This discrepancy may lead to the thought that the 9th overload does not use move semantics. I would suggest either in both cases to have the note on the element being moved, or in both cases not mention it due to it being implicit due to the move semantics of the operand.
- It's a bit of a template hell atm, but agree it'd be worth phrasing in that move acknowledging way. For the time being, worth pointing out that the return value description addresses the case of ctor (9); it always gets moved from, either into the map or into the returned result. --Ybab321 (talk) 08:20, 30 October 2024 (PDT)
[edit] std::optional should mention std::expected
I think std::optional should at least mention std::expected. (std::expected has a "See also" entry for std::optional.) -- Tea2Min (talk) 02:16, 31 October 2024 (PDT)
[edit] Variable name mismatch for rotr doc
https://en.cppreference.com/w/cpp/numeric/rotr takes x & s arguments, but in the text it contains multiple mentions of an "r" variable.
- "r" is defined by the leading sentence
- > Formally, let
N
be std::numeric_limits<T>::digits,r
be s % N.
- > Formally, let
- ✘ Not done --Ybab321 (talk) 08:21, 31 October 2024 (PDT)
[edit] std::this_thread::get_id()
I assume it is a typo - it should be simply:
`std::thread::get_id()`
[edit]
The std::ranges Symbol Index currently doesn't mention std::ranges::binary_search, std::ranges::equal_range, std::ranges::lower_bound and std::ranges::upper_bound (also, the lc template doesn't work for these symbols).
Mystaravinthor (talk) 04:40, 3 November 2024 (PST)
- ✔ Done, i.e. these symbols (algos) where added, (whilst lc template is W.I.P.) Thanks.) --Space Mission (talk) 10:41, 25 November 2024 (PST)
[edit] Add unary operator in lambda function
I only find a tiny sentence about the unary operator for lambda function in https://en.cppreference.com/w/cpp/language/operator_arithmetic
Quote: For example, char is converted to int , and non-generic captureless lambda expression is converted to function pointer(since C++11) in unary plus expressions.
This feature should added in cpp/language/lambda with some examples. For example: https://www.cppstories.com/2020/08/c-lambda-week-some-tricks.html/
Bansan (talk) 02:28, 4 November 2024 (PST)
- The implicit conversion to function pointer type for captureless lambdas is specified here. Unary
+
is one (slightly obscure) way of invoking the conversion, unary*
is another way (which dereferences the implicitly-converted-to function pointer into a function reference), and several usual ways of inducing implicit conversion (mainly initialising a function pointer variable). - Because it's an implicit conversion, I can't immediately think of any situations where explicitly asking for the cast using the unary
+
expression is useful; and without something useful to say, generally speaking, I don't think it's worth talking about the operations on a type that a class implicitly converts to --Ybab321 (talk) 02:46, 4 November 2024 (PST)
[edit] Template Parameter Mismatch
page: [20]
In the function prototype: template< class T1, class T2 > std::pair<V1, V2> make_pair( T1&& t, T2&& u );
It seems that the return type std::pair<V1, V2> is incorrectly specified. It should instead reflect the template parameters T1 and T2 as follows:
template< class T1, class T2 > std::pair<T1, T2> make_pair( T1&& t, T2&& u );
- You'd think so, but there's two reasons this isn't true. Note that
V1
andV2
are defined in the descriptive text of that page. - First reason is that the new function signature takes a reference instead of a value parameter. However, std::make_pair is designed to result in a pair of values (not references). To emulate the semantics of a value parameter, a "decay" of the reference parameter is used. This will do function reference -> function pointer conversion, array reference to array element pointer conversion, etc. Furthermore, a forwarding reference parameter
T1&&
that is passed an lvalue argument of typeT
will deduceT1
as const T&, the decay transformation to the type get srid of the cv and reference qualification. - Second reason is to support the special unwrapping behaviour that std::make_pair applies to std::reference_Wrapper, which, contrary to what I wrote above, does result in a pair containing a reference. So you can consider std::reference_wrapper to be a vehicle that opts into having references, which mirrors what std::thread et al do for their arguments.
- As an aside, I do typically recommend away from using std::make_pair in C++17 codebases (which can just use the std::pair constructor), because these special semantics are usually not something you're looking for, and I find most C++ coders are (understandably) not aware of them. --Ybab321 (talk) 10:52, 4 November 2024 (PST)
[edit] std::c16rtomb should mention std::c8rtomb and vice versa
I think std::c16rtomb should mention std::c8rtomb, and vice versa, and similarly for std::mbrtoc16 and std::mbrtoc8. Then again, there's other similar conversion functions, and they are all mentioned at Null-terminated multibyte strings so perhaps that's enough. -- Tea2Min (talk) 02:08, 5 November 2024 (PST)
- ✔ Done.) --Space Mission (talk) 14:47, 23 November 2024 (PST)
[edit] apple-clang 16 update
Could someone with the write-privilege update 'C++ compiler support' for apple-clang 16 update? Resources can be found here: C++ language support. Thank you.
- ✔ Done. --Space Mission (talk) 12:17, 23 January 2025 (PST)
[edit] Suggestions for cpp/language/acronyms
- IIILE: The name originated from the JavaScript community as Immediately Invoked Function Expression, though rediscovered in multiple languages since. Its purpose in JavaScript is different from in C++.
- IWYU: In addition to the thus-named tool, it is also mentioned in a section of Google's C++ Style Guide. (But which one came first?)
--Kakurady (talk) 06:10, 6 November 2024 (PST)
[edit] List of open-source C++ libraries — Adding Brisk library
I’d like to suggest adding the following library to the Graphical User Interface section:
https://github.com/brisklib/brisk
Brisk, Cross-platform C++20 GUI framework featuring MVVM architecture, reactive capabilities, and scalable, accelerated GPU rendering.
License — GPL/Proprietary, Configuration — cmake, vcpkg.
Their website https://brisklib.com and documentation https://docs.brisklib.com
Note: by the author of KFR (C++ DSP library, 1.7 kstars).
Or, in wiki format: {{librow | Brisk | https://github.com/brisklib/brisk | Cross-platform C++20 GUI framework featuring MVVM architecture, reactive capabilities, and scalable, accelerated GPU rendering. | GPL2+/Proprietary | cmake, vcpkg}}
--F.z.ha (talk) 06:34, 6 November 2024 (PST)
- ✔ Done: Brisk has been added, here.) --Space Mission (talk) 14:29, 23 November 2024 (PST)
[edit] Missing link to std::projected_value_t
On page: https://en.cppreference.com/w/cpp/algorithm/ranges/binary_search
The C++26 versions changed the template parameters. The std::projected_value_t in class T = std::projected_value_t<ranges::iterator_t<R>, Proj> is not linked to this page though: https://en.cppreference.com/w/cpp/iterator/projected_value_t
--jdoubleu (talk) 03:30, 10 November 2024 (PST)
[edit] Broken link to dark theme
In the page https://en.cppreference.com/w/Cppreference:FAQ there is broken link to dark theme: https://userstyles.org/styles/127535/cpp-reference-dark in the "Can you make the site easier to view?" section.
[edit] Fix Typo
Change "the declaraion of std::ios_base::failure::~failure()
" to "the declaration of std::ios_base::failure::~failure()
"
The only change is "declaraion" to "declaration". The rest is for context. 68.179.136.247 08:31, 15 November 2024 (PST)
[edit] Typo in cpp/meta
- Most of non-transforming type traits need to be publicly and unambiguously derived from std::integeral_constant in order to satisfy the requirements of UnaryTypeTrait or BinaryTypeTrait.
"integeral_constant" should be "integral_constant" --83.45.106.143 08:31, 20 November 2024 (PST)
[edit] Update NVC++ column on C++20 compiler conformance page
On the "Compiler support for C++20" page ( https://en.cppreference.com/w/cpp/compiler_support/20 ), please update the "Nvidia HPC C++ (ex PGI)" column of the "C++20 core language features" column. For the rows listed, put the given text in the Nvidia HPC column.
Lambdas in unevaluated contexts: 20.7 Class types in Non-type template parameters: 21.3 std::is_constant_evaluated(): 21.1 Coroutines: 23.3* (the popup text is "with -fcoroutines option") Stronger Unicode requirements: Yes using enum: 22.5 class template argument deduction for alias templates: 23.9 class template argument deduction for aggregates: 23.3 Inconsistencies with non-type template parameters: 21.3 DR98: Pseudo-destructors end object lifetimes: Yes
(I am a developer for the NVIDIA HPC C++ compiler and I have personally tested every one of these features.)
Sorry for the poor formatting on by previous entry. This should hopefully be clearer:
* Lambdas in unevaluated contexts: 20.7 * Class types in Non-type template parameters: 21.3 * std::is_constant_evaluated(): 21.1 * Coroutines: 23.3* (the popup text is "with -fcoroutines option") * Stronger Unicode requirements: Yes * using enum: 22.5 * class template argument deduction for alias templates: 23.9 * class template argument deduction for aggregates: 23.3 * Inconsistencies with non-type template parameters: 21.3 * DR98: Pseudo-destructors end object lifetimes: Yes
Merged two sections into this one. --Space Mission (talk) 10:18, 25 November 2024 (PST)
Dkolsen (talk) 10:23, 20 November 2024 (PST)
[edit] Please add Jsonifier library.
It's very high performance and its link is here: https://github.com/RealTimeChris/Jsonifier. Cheers!
- ✔ Added: here. --Space Mission (talk) 10:18, 25 November 2024 (PST)
[edit] Removal request
Remove Template:cpp/atomic/atomic/address. Made by mistake. Benio (talk) 17:53, 24 November 2024 (PST)
- ✔ Done by T.Canens. --Space Mission (talk) 10:18, 25 November 2024 (PST)
[edit] typo in page Exceptions
Second paragraph: "Evaluating a throw expression will thrown an exception." Should be "Evaluating a throw expression will throw an exception." Thanks
- ✔ Fixed @ cpp/language/exceptions page. --Space Mission (talk) 10:18, 25 November 2024 (PST)
[edit] "cpp/compiler support/20" page suggestion- (I'm new user, can't edit "Talk:cpp/compiler_support/20")
Page "https://en.cppreference.com/w/cpp/compiler_support#C.2B.2B20_library_features" in row with "Text formatting" in first cell, tooltip near value "14*" says: "Support is considered experimental and the -fexperimental-library compiler flag is required".
In my opinion it should say: "Support is considered experimental and the -fexperimental-library compiler flag and clang version >= 15 is required" as clang 14 or earlier doesn't support "-fexperimental-library" flag.
[edit] Missing noexcept
I think this function prototype should have a noexcept like (2):
std::uintmax_t remove_all( const std::filesystem::path& p, std::error_code& ec ); (4) (since C++17) 50.169.69.125 12:57, 26 November 2024 (PST)
- Doesn't look like it https://eel.is/c++draft/fs.op.remove.all ✘ Not done --Ybab321 (talk) 16:50, 26 November 2024 (PST)
On https://en.cppreference.com/w/cpp/keyword/static , the 2nd link to "definitions of block scope variables with static storage duration and initialized once" is incorrect. Currently pointing at https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables Instead it should be https://en.cppreference.com/w/cpp/language/storage_duration#Static_block_variables ("block" instead of "local".
(I've tried to edit it directly, but I'm somehow considered a "new user", I guess 9 years is not enough :-P ) Thanks.
[edit] corrections to apply for the examples in CTAD page
On the page: [21]
the examples:
A a5 = {0, 1}; // error: #3 deduces to A<int&>
// and #1 & #2 result in same parameter constructors.
A a6{0, 1}; // OK, #4 deduces to A<int> and #2 initializes A a7 = {0, i}; // error: #3 deduces to A<int&> A a8{0, i}; // error: #3 deduces to A<int&>
are not aligned to the standard about comments.
In particular, only a6 is aligned, whereas the comment I see here for a5 is applied by the standard to a7 and a8.
About a7 and a8, see also [22] and [23] about the fact that the comment is also wrong and should be fixed.
Mauro russo (talk) 12:36, 27 November 2024 (PST)mauro_russo
Wanted to edit https://en.cppreference.com/w/cpp/algorithm/find because its example has a weird mix of `v.begin()`, `v.end()` and `std::end(v)`. But I seem to not be allowed to do it. Martijntje (talk) 08:09, 28 November 2024 (PST)
[edit] [std::expeceted] Plural where singular should be used.
Documentation of std::expected<void,E>::~expected() (see here).
The last sentence is in plural while it should be in singular.
- ✔ Done fixed. --D41D8CD98F (talk) 01:23, 3 December 2024 (PST)
[edit] [C++20--26 support] Remove entries for moribund compilers
There are a number of C++ compilers that never made the transition to C++20, and are making our support look bad by the overwhelming number of red cells for C++26. C++23, and C++20. I suggest removing the following compilers (and libraries) from the main page that covers C++20--C++26:
- IBM XL C++
- IBM Open XL C++ for AIX
- IBM Open XL C++ for z/OS
- Sun/Oracle C++
- Embarcadero C++ Builder
There is good reason to believe that some of these will never make the transition, such as Sun/Oracle C++. It would be relatively easy to restore any of these compilers if they do catch up --- I still have hopes for Embarcadero C++ Builder.
The corresponding library entries would be:
- IBM Open XL C/C++ for AIX
- Sun/Oracle C++*
- Embarcadero C++ Builder
Note that while several active C++20 compilers show no progress on C++23, that might be expected when C++20 was still the latest ISO standard until as recently as a month or so ago ago. There is no suggestion that those compilers are moribund yet.
AlisdairM (talk) 05:59, 29 November 2024 (PST)AlisdairM
- ✔ Done, I think, as suggested. :-) The root link to these tables: cpp/compiler support --Space Mission (talk) 20:26, 8 December 2024 (PST)
[edit] &std::endl is not a valid expression.
The "lvalue" section of Value categories says "&std::endl" is a valid expression. But this expression causes a compiler error even though it is lvalue because std::endl is an overloaded function. So I suggest removing the claim that "&std::endl" is a valid expression.
- It's valid as a subexpression of something like void f(std::ostream&(*)(std::ostream&)); f(&std::endl); or static_cast<std::ostream&(*)(std::ostream&)>(&std::endl);, which I think would be a little noisy to write out in full. It's unfortunate that there aren't better suitable functions in the standard library to use for this example. Could maybe change it to an invented &func and hope it's clear from the context though(?) --Ybab321 (talk) 03:32, 3 December 2024 (PST)
[edit] Misinformation on std::array<T,N>::data
At the top of the page, it is stated that the const variant is "constexpr since C++14", which should have been "constexpr since C++17". Maza91 (talk) 04:48, 4 December 2024 (PST)
[edit] Removal or Update of warning from C++ assume() attribute page
The second paragraph on this page seems to be more of a command to the reader that only conveys derivative information. I think it should be revised or removed to rather elaborate further on the meaning and precise behavior assume instead. For example:
The assumed expression is not executed. If the expression would evaluate to false, or would fail to evaluate entirely, the behavior is undefined. This allows the compiler to emit different assembly under the assumption that the condition would evaluate to true.
The comment also seems to be aimed at deterring people away from a valid feature of the language. The page should be neutral and solely informative, and readers should decide for themselves whether the feature is useful to them or not. --Kröw (talk) 20:53, 6 December 2024 (PST)
- Removed the second paragraph, and updated the first paragraph to clarify that the nature of
[[assume]]
is an assumption rather than an instruction.✔ Done --Xmcgcg (talk) 08:14, 7 December 2024 (PST)
page url: https://en.cppreference.com/w/cpp/memory/shared_ptr/atomic
5) Stores the shared pointer r in the shared pointer pointed-to by p atomically, as if by p->swap(r).
As with the non-specialized std::atomic_store_explicit, if mo is std::memory_order_release or std::memory_order_acq_rel, the behavior is undefined.
In the above descriptioin, std::memory_order_release should be std::memory_order_acquire. Please confirm.Thanks!
[edit] Wrong statement Linkage ->Internal Linkage
In the section "Linkage -> internal linkage" on the following site there has been an error: https://en.cppreference.com/w/c/language/storage_class_specifiers
Quote: "All variables which are declared at file scope have this linkage, including variables declared static at file scope." This is wrong when reading the C-Standard N2310 (C17) as linked on cppreference.com https://www.open-std.org/jtc1/sc22/wg14/www/projects#9899
The standard states in section 6.2.2 phrase 5: "If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external."
I propose the sentence "All variables declared at file scope and without a storage-class specifier have external linkage. Variables at file scope declared static have internal linkage."
2001:470:72B4:100:DD46:376C:DABD:395B 03:09, 10 December 2024 (PST)
- Have added some fixes, I'm a little astonished at how wrong it was... ✔ Done --Ybab321 (talk) 05:47, 10 December 2024 (PST)
[edit] Complexity of flat_set::emplace is incorrect
Link: https://en.cppreference.com/w/cpp/container/flat_set/emplace That page includes a template `cpp/container/emplace_assoc` with `|flat_set`, however, that template seems handle only flat_map.
[edit] Possible typo in https://en.cppreference.com/w/cpp/container/flat_map/extract
(I may have misunderstood the intent but...)
The example code cannot yet be run (under neither GCC 13, GCC 14 nor clang 9) as no compiler can find the <flat_map> header.
However, in the example, line 21 asserts that the type of the extracted value-vector is std::vector<int>. Surely this should be std::vector<double>?
[edit] Is the possible implementation wrong about forward_like TTPS ?
Good morning,
The possible implementation shows `detail::type_forward_like_t<Self, T..., std::decay_t<Args>>...`, while only takes two TTP as arguments `template <class T, class U> using type_forward_like_t;`
While bind_back impls noexcept and trailing return type forward T... like Self, while I'd expect Args... to be forwarded like Self, and T... to be perfect-forwarded.
Quick demo: https://godbolt.org/z/c49K7s35K
2A01:CB00:8BCA:8200:C45C:925C:A46:D646 00:51, 17 December 2024 (PST)
pro.guillaume.dua@gmail.com
- Tbh I'm not sure what the point of that possible impl is, it's far too complicated and awkward to have any edificational value. Think we should remove it, or at best link to an stdlib impl --Ybab321 (talk) 02:50, 17 December 2024 (PST)
[edit] cpp/io/manip/fixed: improve comment on platform-dependent arithmetic extractor
Page https://en.cppreference.com/w/cpp/io/manip/fixed contains example code that contains the comment "Note; choose clang for correct output".
For clarity, I suggest the wording: "Works only under Clang".
For correctness, I suggest the addition: "Behavior depends on locale". Because, depending on your locale, the example may or may not work.
- that's not a locale-dependent example. The example happens to demonstrate a buggy standard library implementation that failed to apply lwg2381 (clang's library implemented it from day one since otherwise hexfloat parsing can't work) --Cubbi (talk) 08:25, 18 December 2024 (PST)
[edit] unordered_multiset/count example
https://en.cppreference.com/w/cpp/container/unordered_multiset/count
this page has an error template parameter int is not given in the example for std::unordered_multiset
- thanks to CTAD a template parameter in that case has not been needed since 2017 --Cubbi (talk) 08:17, 18 December 2024 (PST)
[edit] Saturating math
the four saturating math opps of C++26 (add_sat, sub_sat, mul_sat, div_sat) each contain the phrase
In particular, T must not be (possibly cv-qualified) bool, char, wchar_t, char8_t, char16_t, and char32_t, as these types are not intended for arithmetic.
This is not accurate to the language of draft n4993
26.10.17.1.2:
2 Constraints: T is a signed or unsigned integer type (6.8.2).
6.8.2:
The types char, wchar_t, char8_t, char16_t, and char32_t are collectively called character types. The character types, bool, the signed and unsigned integer types, and cv-qualified versions (6.8.5) thereof, are collectively termed integral types. A synonym for integral type is integer type
You can absolutely do saturate math with bool, char, wchar_t, char8_t, char16_y and char32_t.
82.134.131.173 01:01, 19 December 2024 (PST) SRNissen
- bool and character types are integral/integer types, but they are neither signed integral types nor unsigned integral types. --Xmcgcg (talk) 16:54, 19 December 2024 (PST)
[edit] Typo on 'new expression' page: Use the correct term "brace-enclosed".
On the page about the new expression, in the Explanation section, in the new-initializer definition, the phrase reads 'braced-enclosed...'. The first word in the hyphenated phrase should be "brace." Using two consecutive words in the past tense is incorrect and technically the term is incorrect even if we ignore correctness of English language usage.
Here is a link to the page: https://en.cppreference.com/w/cpp/language/new
2A09:BAC3:16C1:123:0:0:1D:BC 06:37, 19 December 2024 (PST) Sauparna Palchowdhury
[edit] Missing std::byte exception for strict aliasing
On https://en.cppreference.com/w/c/language/object all the exceptions to strict aliasing are listed, but std::byte is missing.
- std::byte is mentioned here, on C++ page: type aliasing, which you can reach via the link strict aliasing (note: C++ not C).
- ✘ Not done :-) --Space Mission (talk) 11:07, 19 December 2024 (PST)
[edit] new C23 feature
As one of the new C23 features, the new tag compatibility rules are missing on the C23 page and in the compiler support table.
N3037 Improved Tag Compatibility
[edit] Useful Resources
I believe the page of useful resources should get updated with blogs or YouTube channels loke the following:
- https://www.fluentcpp.com
- https://www.modernescpp.com/index.php/blog/
- https://youtube.com/@cppweekly?si=7erGZRUVrepDyOvh
- https://youtube.com/@cppcon?si=f4BWMCRopjK4hyQm
- https://www.cppstories.com/
- https://cppsenioreas.wordpress.com
[edit] Fixing operator precedence page for consistency
Hello,
I noticed an inconsistency in the operator precedence table from https://en.cppreference.com/w/cpp/language/operator_precedence. For most operators, operands like a and b are omitted (e.g., >>, >=, ^, |, etc.), but for the bitwise AND operator (&), it includes a&b.
To improve clarity and consistency across the table, I suggest either:
Removing the a and b from a&b, or Adding similar operands (e.g., a>>b, a>=b, a^b, a|b, etc.) to the other operators.
This small adjustment would ensure uniformity in presentation and reduce any potential confusion for readers.
Best regards, N1PE.
- Yep, operands have been added with additional formatting.) ✔ Done --Space Mission (talk) 21:20, 24 December 2024 (PST)
[edit] std::ranges::set_intersection
set_union_result instead of set_intersection_result in Possible implementation section. --ddvamp (talk) 10:22, 25 December 2024 (PST)
- ✔ Fixed, thanks. --Space Mission (talk) 12:13, 25 December 2024 (PST)
[edit] `type_identity`: Additional example of usage
The current example for `std::type_identity` demonstrates how we can eliminate template argument deduction for one or more function call arguments.
I wish to suggest that an additional example is added, for a totally different use.
Please see:
- Andrei Alexandrescu's 2001 book ("Modern C++ Design: Generic Programming and Design Patterns Applied"), Section 2.5 ("Type-to-Type Mapping"). It defines: `template <typename T> struct Type2Type { typedef T OriginalType; };` and it explains the usage -- to work-around the fact that function templates cannot be partially specialized.
- Usage in the open-source Loki Library ([24] -- files `TypeManip.h` and `AbstractFactory.h`).
I think such usage is even more interesting than the one already in the current example for `std::type_identity`. After all, the current example works fine for `bar (4.2, 1)`, but probably does not work fine for `bar (1, 4.2)`.
Whatever you decide, thank you for the work on cppreference.com and Merry Xmas and Happy New Year !!
--DoctorNoobingstoneIPresume (talk) 15:17, 25 December 2024 (PST)
- Thanks for the kind words :)
- I think that use is rather esoteric tbh. One doesn't in general need to simulate partial specialisation for function templates, because they support overloading (and in fact, partial specialisation for class templates are implemented using function overloading). --Ybab321 (talk) 06:38, 26 December 2024 (PST)
- Loki is a product of its age, C++ moved on. As for enriching cpp/types/type_identity, we could always add other motivations listed in p0887 --Cubbi (talk) 20:56, 26 December 2024 (PST)
[edit] Condition of move constructor's implicit definition
In a __Trivial move constructor__ section where it begins with "If the implicitly-declared move constructor is neither deleted nor trivial..." I think the condition of implicit definition of implicitly-declared move constructor should be "either not deleted or trivial" or "neither deleted nor non-trivial" from "neither deleted nor trivial"
Or is it correct that move constructor is implicitly defined when implicitly-declared move constructor is not trivial?
[edit] std::unordered_map [] operator : requirement "mapped_type must be DefaultConstructible." is misleading
https://en.cppreference.com/w/cpp/container/unordered_map/operator_at
In above page "mapped_type must be DefaultConstructible." is incorrect and it should account for the fact that we can use fundamental types such as int as value and still it will compile because even if it is not DefaultConstructible but it can be value initialised. so it should say
for fundamental types, "DefaultConstructible" effectively means "value-initializable to a default value" in this context.
[edit] std::format effects are hard to find
Trying to find the effects of std::format is a tough job:
- The link from https://en.cppreference.com/w/cpp/utility/format/format is in a fairly obscure location, in the middle of a text block, instead of prominently displayed.
- The actual page, https://en.cppreference.com/w/cpp/utility/format/spec, explains the effects of many formatting options by reference to std::to_chars.
- The std::to_chars page, https://en.cppreference.com/w/cpp/utility/to_chars, explains the effects of many formatting options by reference to std::printf.
- That page, https://en.cppreference.com/w/cpp/io/c/fprintf, finally has the desired information.
SPOT is a great principle in programming, but it's not so great in documentation. Would it be an idea to make the format/spec page self-sufficient? I.e. not require clicking through to two further pages just to find out what the various options do?
And also, maybe make the link to format/spec more prominent on the std::format page?
Johannes1971 (talk) 04:49, 29 December 2024 (PST)
- I am planning for a fix. The first issue can be fixed by adding a table of the final formatting effect to cpp/utility/format/spec. The second issue can be fixed by rearranging the descriptions of format strings. --Xmcgcg (talk) 06:57, 29 December 2024 (PST)
[edit] What does "formally" mean?
In the webpage of "[typeid operator] https://en.cppreference.com/w/cpp/language/typeid", a sentence reads "Temporary materialization, however, is (formally) performed for prvalue arguments: ..." I am confused by the meaning of "formally" here. If it means "semantically", that is, the execution model of the standard assumes that a temporary materialization is conducted, but this materialization can be optimized out by the compiler in practice, I think maybe "(semantically)" is a better wording than "(formally)".
As a side note, I am also confused by the difference between temporary materialization and evaluation in case the argument is an rvalue Derived(). In other words, I can't figure out how to temporarily materialize a polymorphic object but does not evaluate it.
- there is no execution in that paragraph (it's under "otherwise, typeid does not evaluate..."), and thus no optimization or anything like that. The parentheses explain what 'formally' tried to convey: that the destructor should be public as would be required if that expression were to be evaluated ( as I just checked, gcc and clang
don't enforce this requirementonly enforces this if the expression further uses imaginary temporary object). The rvalue expression Derived() is the same: no evaluation takes place, typeid shows the static type of the expression,Derived
, baked in at compile time. --Cubbi (talk) 18:21, 1 January 2025 (PST)
[edit] c/language/ Static assert (version fix in line 4)
{{title|Static assertion {{mark since c11}}}} {{c/language/declarations/navbar}} ===Syntax=== {{sdsc begin}} {{sdsc|notes={{mark since c11}}{{mark deprecated c23}}|{{ttb|_Static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|,}} {{spar|message}} {{ttb|)}}}} {{sdsc|notes={{mark since c23}}|{{ttb|static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|,}} {{spar|message}} {{ttb|)}}}} {{sdsc|notes={{mark since c11}}{{mark deprecated c23}}|{{ttb|_Static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|)}}}} {{sdsc|notes={{mark since c23}}|{{ttb|static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|)}}}} {{sdsc end}} ...
- Edited to re-enable this page accessibility, --Space Mission (talk) 08:45, 1 January 2025 (PST)
- Nope, the 4th line is okay, _Static_assert without 2nd argument is C23 feature.) ✘ Not done. --Space Mission (talk) 08:45, 1 January 2025 (PST)
[edit] Follow up of "What does 'formally' mean?"
I don't know how to follow up right below a message, so I have to new a talk. I would appreciate it if someone could teach me the former.
If "(formally)" means "the argument must be destructible" or equivalently "destructor should be public" as Cubbi answers, I have to say such a meaning is so esoteric. Does such a meaning of "formally" formally appear somewhere in C++ standard? If so, I would accept it, but if not, I have to request to remove the usage of "(formally)" this way and to replace it with some more accessible wording. After all, contents of cppreference webpages are created to be human-readable.
And as a result, I still don't understand the meaning of that paragraph (starting with "Temporary materialization, however, ..." under "otherwise, typeid does not evaluate..."). Cubbi replied that there is no execution there. What does "Temporary materialization ... is ... performed" mean then? Does performance of temporary materialization count for some kind of execution?
- (for context, this is about cpp/language/typeid's phrasing of https://eel.is/c++draft/expr.typeid#5.sentence-3 ) It is the same as any operation that appears inside unevaluated context: is performed "formally", "on paper", "in theory", not in actual reality. (in actual reality, the AST is constructed after the expression source code is parsed and the front-end queries the static type of its root node). --Cubbi (talk) 12:05, 10 January 2025 (PST)
And I am still confused about the difference between "temporary materialization" and "evaluation" when it comes to typeid(Derived()) if Derived is a polymorphic class. If "temporary materialization" and "evaluation" are the same, Derived() is not evaluated because it is an rvalue; but how about "Temporary materialization ... is ... performed"? If "temporary materialization" is not "evaluation", what does "evaluation" do? I have some vague understanding that evaluation means "getting the value of". But what value does typeid try to get when it evaluates an object of a polymorphic type in typeid(d) where d is defined as "Derived d();" and thus a lvalue. Thanks for further clarification.
- evaluation transforms an expression into its result: evaluation of 1+1 results in value 2. But in unevaluated context, such as typeid(1+1), addition is not actually performed, the number 2 is not obtained in any form. Temporary materialization relates to evaluation just as addition relates to evaluation, it's just that there is no dedicated symbol in the source code for it. --Cubbi (talk) 12:05, 10 January 2025 (PST)
[edit] How could "an lvalue-to-rvalue conversion is applied to an expression E" if "E is not potentially evaluated"?
I am confused by the wording in paragraph beginning with "When an lvalue-to-rvalue conversion is applied to an expression ..." in [Lvalue-to-rvalue conversion https://en.cppreference.com/w/cpp/language/implicit_conversion#Lvalue-to-rvalue_conversion]. If "E is not potentially evaluated," for example, in sizeof(E), lvalue-to-rvalue will not be performed for E according to the document of [sizeof operator https://en.cppreference.com/w/cpp/language/sizeof]. Then how could "an lvalue-to-rvalue conversion is applied to an expression E" in the first place? I really cannot figure out an example of sizeof(E) in which E is not potentially evaluated (equivalent to saying E is an unevaluated operand), but an lvalue-to-rvalue conversion is applied somehow to it.
- you're now on https://eel.is/c++draft/expr.sizeof#3 which is a mirror copy of https://eel.is/c++draft/expr.typeid#5 l2r is another operation for which we have no symbol in source code. If you want to see those invisible steps, print the AST (clang does it nicely): the materialization node should be there in the argument of sizeof, but the l2r conversion node should not be there. --Cubbi (talk) 12:05, 10 January 2025 (PST)
[edit] Improve example of std::variant<Types...>::visit
- Add "#include <iomanip>" and using std::quoted for string output.
- Add "#include <string_view>" and receive string as std::string_view.
- Add "#include <version>" for feature testing.
- Use alias 'var_t' like example of std::visit.
- Add visiting 'Derived' to 'Base'. (Implicit conversion during INVOKE)
- Use 'visitor' auto variable for reuse.
I'm not familiar with the wiki format, so I wrote 'Derived()' instead of 'Derived{}'. It may contain incorrect content or look a bit messy and may need to be removed.
#include <iomanip> #include <iostream> #include <string> #include <string_view> #include <variant> #include <version> struct Base {}; struct Derived : Base {}; // the variant to visit using var_t = std::variant<int, std::string, Derived>; // helper type for the visitor template<class... Ts> struct overloads : Ts... { using Ts::operator()...; }; int main() { var_t var1{42}, var2{"abc"}, var3{Derived()}; auto use_int = [](int i){ std::cout << "int = " << i << '\n'; }; auto use_str = [](std::string_view sv){ std::cout << "string = " << std::quoted(sv) << '\n'; }; auto use_base = []([[maybe_unused]] Base b){ std::cout << "base\n"; }; auto visitor = overloads{use_int, use_str, use_base}; #if (__cpp_lib_variant >= 202306L) var1.visit(visitor); var2.visit(visitor); var3.visit(visitor); #else std::visit(visitor, var1); std::visit(visitor, var2); std::visit(visitor, var3); #endif }
Output:
int = 42 string = "abc" base
Khkgn (talk) 22:32, 2 January 2025 (PST)
- Good suggestions, updated, thanks. Switched over to std::print, elided the unhelpful lambda names, opted for the more conventional equals syntax for init, Derived() is perfectly appropriate. ✔ Done --Ybab321 (talk) 05:05, 3 January 2025 (PST)
[edit] Too many closing angle brackets on constructors 4 and 5 of std::expected
In the "Constraints and supplement information" section, for constructors 4 and 5
- std::is_convertible_v<std::expected<U, G>&, T>>
- std::is_convertible_v<std::expected<U, G>, T>>
- std::is_convertible_v<const std::expected<U, G>&, T>>
- std::is_convertible_v<const std::expected<U, G>, T>>
On these four lines, there are too many closing angle brackets (the last one should be removed).
Simon Cros (talk) 05:16, 3 January 2025 (PST)
- ✔ Done by Cooky. --Space Mission (talk) 12:30, 3 January 2025 (PST)
[edit] Mistake of logging output in std::any_cast
The code:
// Advanced example
a1 = std::string("hello"); auto& ra = std::any_cast<std::string&>(a1); //< reference ra[1] = 'o'; std::cout << "4) a1 is string: " << std::any_cast<std::string const&>(a1) << '\n'; //< const reference
The log:
4) a1 is string: hollo
--213.216.111.147 00:40, 8 January 2025 (PST)
- The Output is okay, because the character sequence "hello" inside std::any object a1 was updated in the statement ra[1] = 'o';. ✘ Not done.) --Space Mission (talk) 03:30, 8 January 2025 (PST)
[edit] Additional Suggestion to C23 Feature Page
"7.23.6 Formatted input/output functions" specify different format specifiers and modifiers for `fprintf` and `fscanf` function family.
One of the modifiers that are not included in the C23 feature list page are %wN and %wfN . For example:
```
uint64_t num = 1234;
printf("A uint64_t number: %w64u\n");
```
It would be helpful to add that to the list.
[edit] Add me to whitelist
Every now and then I see small errors that I could quickly fix, but I would have to go through the suggestion page since I don't have editing powers. Since I already contributed two times in the past, once through the suggestion page and once by myself before the editing lock down, I think I can be considered trustworthy (in the sense that I'm not a vandal). Can I be added to the whitelist?
--ThePirate42 (talk) 09:40, 9 January 2025 (PST)
[edit] The C compiler support pages are broken
See c/compiler support. All the links are broken. 2A10:9300:400:29C0:1965:2289:6C96:EE52 14:57, 9 January 2025 (PST)
- ✔ They are fixed now, Δόξα στον Προμηθέα!. I completely forgot that the C compiler support tables also use {{compiler_support_row}} along with similar C++ tables. Thanks for the reminder and best wishes.) --Space Mission (talk) 16:25, 12 January 2025 (PST)
[edit] Typo in https://en.cppreference.com/w/cpp/atomic/atomic_flag example
in https://en.cppreference.com/w/cpp/atomic/atomic_flag example, line 18, missing the first 'a' in 'guarantees'
[edit] Invalid description for "alignas" and "alignof"
On the page: https://en.cppreference.com/w/c/types
There are following two lines:
alignas (C11)(removed in C23) convenience macro, expands to keyword _Alignas
alignof (C11)(removed in C23) convenience macro, expands to keyword _Alignof
But I think they should be like this:
alignas (C11)(since C23) convenience macro, expands to keyword _Alignas
alignof (C11)(since C23) convenience macro, expands to keyword _Alignof
The same probably applies to lines with bool, true and false.
- The macros were removed since they were promoted to keywords, perhaps it would be useful to link the keywords... --Ybab321 (talk) 05:28, 10 January 2025 (PST)
[edit] std::basic_string::erase function breaks iterator, but wiki doesn't mention that.
Hi,
Documentation for std::basic_string::erase, specifically (1) / "basic_string& erase( size_type index = 0, size_type count = npos );"
does not indicate associated iterators being affected. However, code such as:
std::string some_string = "hello"; for (auto c : some_string) { // do something with c some_string.erase(0, 1); }
will break. Should there be a mention of this on the wiki?
2001:9E8:119A:E901:A3EB:976B:D0A8:F479 15:42, 10 January 2025 (PST)
- It is mentioned in the Iterator invalidation section of the std::basic_string paqge. --Xmcgcg (talk) 19:52, 10 January 2025 (PST)
[edit] LWG3539 applies to all four std::format_to overloads
https://en.cppreference.com/w/cpp/utility/format/format_to
https://cplusplus.github.io/LWG/issue3539
Cppreference currently misses `std::move` for `char`-overloads.
- Fixed.✔ Done --Xmcgcg (talk) 17:59, 13 January 2025 (PST)
- No, it applies to C++23, not C++20. And 2 overlods in "Equivalent to" paragraph also need fix. --E5d5df (talk) 02:23, 15 January 2025 (PST)
- Now it should be fixed. The issue still targets C++20 because it is clearly not the intent of the author of the std::format_to proposal to exclude move-only iterators. --Xmcgcg (talk) 16:53, 15 January 2025 (PST)
- No, it applies to C++23, not C++20. And 2 overlods in "Equivalent to" paragraph also need fix. --E5d5df (talk) 02:23, 15 January 2025 (PST)
[edit] all_of wrong documented Return value
Hi, in
https://en.cppreference.com/w/cpp/algorithm/all_any_none_of
there is a truth-table in the section "Return value"
"all_of" lists "true" for the case ["no", "no"], which is, I believe, wrong.
I also miss a concise documentation for the default values returned if the given range is empty. It is deducible from the given code-snippets, but i feel like that is not how it should be documented.
- The standard says
all_of
returns “false if the predicate result is false for some iterator i in the range[
first,
last)
, and true otherwise”, I updated the wording to clarify that. Empty range simply falls into the no-no case, and I also added a note about this. --Xmcgcg (talk) 17:59, 13 January 2025 (PST)
[edit] string_literal from cpp page is incomplete!
https://en.cppreference.com/w/cpp/language/string_literal is incomplete, it doesn't have the literals explanations found in https://en.cppreference.com/w/c/language/string_literal
Solution --- Copy the https://en.cppreference.com/w/c/language/string_literal to https://en.cppreference.com/w/cpp/language/string_literal
Aitorhub (talk) 06:54, 14 January 2025 (PST)
- ✘ No change required.
- The string concatenation part is documented in the Concatenation section.
- The modifiability part does not apply in C++ because string literals in C++ have type const CharT[N], the const qualification already implies that string literals are not modifiable.
- The overlapping memory part is documented in the Address section of cpp/language/object.
- --Xmcgcg (talk) 17:25, 14 January 2025 (PST)
[edit] XCode support of C++20/23/26 update
The C++ standard support templates currently do not take Xcode 16 into account. The additionally supported features are listed on the release notes page of Xcode 16.
I tried to update those templates myself, but unfortunately I cannot edit them yet due to having a new account. So it would be nice if someone with the required access could update those templates.
- ✔ Done. The template {{aclang ver/num}} was updated with Xcode-16 and newly supported by Xcode/aclang C++ features were added to C++20/23/26 compiler support pages.) --Space Mission (talk) 11:19, 23 January 2025 (PST)
[edit] offsetof cannot be implemented in standard C++ and requires compiler support:
The statement: "offsetof cannot be implemented in standard C++ and requires compiler support" is incorrect.
In the MSVC it's implemented by standard language means:
#define offsetof(s,m) ((::size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
- pretty sure this expression is neither standard C++ nor implements offsetof as specified: it fails the (inherited from C) requirement to be a constant due to use of reinterpret_cast - clang told me "note: cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression" and due to null pointer dereference UB - gcc told me "error: dereferencing a null pointer in '*0'"). Aside that, what offsetof even supposed to do is a hot open issue right now; see wg21.link/cwg2784 and wg21.link/p2883 --Cubbi (talk) 10:47, 15 January 2025 (PST)
[edit] Removed <typeinfo>, it didn't commit anything to the output
-- snipped paste of cpp/types/bad_cast--
- #include <typeinfo> is necessary in the example because that's where std::bad_cast is defined. It just happens to be included by gcc's iostream transitively. --Cubbi (talk) 10:52, 15 January 2025 (PST)
[edit] = memory_order_seq_cst of store descripted not strong enough
store(x, memory_order_seq_cst) looks like has both acquire to later R/W and release to prev R/W. And store(x, memory_order_seq_cst) will prevent store-load reorder. So why it's descriped that "A load operation with this memory order performs an acquire operation, a store performs a release operation, and read-modify-write performs both an acquire operation and a release operation, plus a single total order exists in which all threads observe all modifications in the same order (see Sequentially-consistent ordering below)"
- it's described exactly as specified AFAICS: seq_cst effect on a store operation is https://eel.is/c++draft/atomics.order#1.2 on a load operation https://eel.is/c++draft/atomics.order#1.4 and the additional total order is https://eel.is/c++draft/atomics.order#4 . Our detailed section cpp/atomic/memory_order#Sequentially-consistent_ordering defines that in detail and even explains how seq_cst is incompatible with acq/rel --Cubbi (talk) 10:46, 17 January 2025 (PST)
[edit] Clarification on string/basic_string/operator""s example
I had trouble understanding why the "abc\0\0def"s example outputs the ₀ characters. That was until I read the constructor page which explains that the ""s operator invokes the constructor which takes the 'size_type count' as the second argument (form 6, if I understand correctly). It would be useful to explain that on the string_literals page. --Rjollos (talk) 17:49, 17 January 2025 (PST)
- The invocation of the std::string ctor ("Returns std::string{str, len}") is in the
operator""s
description, in fact it's the only thing in the description. --Ybab321 (talk) 03:08, 18 January 2025 (PST)
[edit] Wrong constructors referenced on expected constructor
In the "Constraints and supplement information > void partial specialization constructors" section, for constructors 16 and 17 :
16,17) These overloads participate in overload resolution only if all following conditions are satisfied:
For overload (4), std::is_constructible_v<E, const G&> is true.
For overload (5), std::is_constructible_v<E, G> is true.
`For overload (4)` and `For overload (5)` are copied from the non specialized section, and should be replaced with `For overload (16)` and `For overload (17)`.
--Simon Cros (talk) 04:25, 18 January 2025 (PST)
[edit] fix std::normal_distribution example to be free of conversion warnings
cpp/numeric/random/normal_distribution#Example
make example compile cleanly under -Wconversion and -Wsign-conversion
changeauto random_int = [&d, &gen]{ return std::round(d(gen)); }; std::map<int, int> hist{};
#include <cstddef> //... auto random_int = [&d, &gen]{ return std::lround(d(gen)); }; std::map<long, std::size_t> hist{};
Oschonrock (talk) 01:26, 21 January 2025 (PST)
The code snippets in this section were wrapped into MediaWiki templates. --Space Mission (talk) 13:45, 23 January 2025 (PST)
- ✔ Done.) --Space Mission (talk) 13:45, 23 January 2025 (PST)
[edit] Error in cpp/algorithm/inplace_merge
In cpp/algorithm/inplace_merge, there is that paragraph:
If any of the following conditions is satisfied, the behavior is undefined:
[
first,
middle)
or[
middle,
last)
is not a valid range.- The output range overlaps with
[
first,
middle)
or[
middle,
last)
.
The second condition, about an "output range", is erroneous and should be removed because there is no output range per se. The output range is [
first,
last)
, and it obviously overlaps with the two other ranges. That is why that is called in place merge.
See the section about that algorithm in the official LaTeX source code of the C++ Draft.
--Laurent Rineau 06:26, 21 January 2025 (PST)
[edit] Add to confirmed group
By the way, I would like to be added to the confirmed group. --Laurent Rineau 06:37, 21 January 2025 (PST)
[edit] C++ assert macro
The C++ assert page says...
assert checks if its argument (which must have scalar type): If the argument compares equal to zero, there are no further effects. Otherwise, assert creates a diagnostic on the standard error stream and calls std::abort().
I think that is inverted for the argument comparison, should be phrased something like:
If the scalar argument does compare equal to zero, then assert outputs implementation-specific diagnostic information on the standard error output and calls std::abort(). Otherwise, there are no further effects.
192.150.22.5 06:14, 24 January 2025 (PST)
[edit] Links to headers do not link to headers
Go to e.g. the page for C malloc (not std::malloc) click the link where it says "Defined in header <stdlib.h>" You will go to a page that does not feature malloc - rather than a page for the stdlib header, it's a page for "program support utilities."
Go to the page for C unreachable (not std::unreachable) click the link where it says "Defined in header <stddef.h>" You will go to a page that does not feature "unreachable" - rather than a page for the stddef header, it's a page for "Type support."
I feel like I've seen this in several other places, but these two are definitely like that. 82.134.131.173 09:29, 24 January 2025 (PST)
- That's unfortunate. I guess we'll have to make some pages for each header like the C++ section has done (optionally with the synopsis). Currently we're using this mapping for the C pages currently, so we can't fix the malloc header link without breaking other stdlib header links. --Ybab321 (talk) 03:44, 25 January 2025 (PST)
- ✔ Done. I've added the necessary infrastructure for C headers by updating the {{header}} template and by adding all (presently – 32) C header pages, so now <stdlib.h> (and others) work and link to their own pages. Yet, the C header pages are severely underdeveloped. I hope this will be fixed eventually.) --Space Mission (talk) 10:38, 16 February 2025 (PST)
[edit] Mistake in std::atomic_ref?
The following change to atomic_ref looks wrong. My account has been around since 2019, but it seems I lost any permissions.
I'd like to discuss this with the contributor, or undo it, because it pretty much now says the opposite of what it should and used to say.
For example, according to this change, `std::atomic_ref<int>` is ill formed.
(cur | prev) 03:22, 14 January 2025 YexuanXiao (Talk | contribs) m . . (5,695 bytes) (+43) . . (undo)
Jodyhagins (talk) 09:09, 26 January 2025 (PST)
[edit] C23 missing changes
I would like to add some missing entries to the C23 page, in particular tag compatibility changes (N3003) and compiler support in GCC. But I can't because editing of this page is not allowed for new users. Any help (either unlocking this page or account settings) or adding this change is much appreciated. Uecker (talk) 02:13, 27 January 2025 (PST)
[edit] Broken link in Empty base optimization page
Simple fix, just a broken link for boost::compressed_pair link.
substitute https://www.boost.org/doc/libs/release/libs/utility/doc/html/boost/compressed_pair.html
with https://www.boost.org/doc/libs/release/libs/utility/doc/html/utility/utilities/compressed_pair.html
[edit] page C / Arithmetic types on other systems
page C / Arithmetic types the table summarizes all available integer types and their properties and the notes below are good. It would be useful if were added the types length on earlier systems, with 16bits word cpus, and or others if there are some. I' am searching this info, I will search the net, yet I don't have the info yet.
2A01:CB0D:CE:5500:6A0A:2A1A:980C:16B1 07:29, 27 January 2025 (PST)
[edit] Typo in https://en.cppreference.com/w/cpp/ranges/subrange
Contains "Determintes", should be "Determines".
Cheers.
[edit] C17 is no longer the current revision of the C standard.
https://en.cppreference.com/w/c/17
Should be updated to reflect that C17 is no longer the current revision of the C standard.
- ✔ Done. Statuses of C Standards were just updated: C11, C17, and C23.) --Space Mission (talk) 16:02, 28 January 2025 (PST)
[edit] std::align example might have UB
An object of type `char` is being type-accessed through a glvalue of type `int` which doesn't follow the rules in https://eel.is/c++draft/basic.lval#11
Maybe it'd be better if `T` were explicitly constructed:
2a3 > #include <new> 16c17 < T* result = reinterpret_cast<T*>(p); --- > T* result = new (p) T;
Seha (talk) 10:00, 28 January 2025 (PST)
[edit] _Static_assert (expression) in C is incorrectly marked since C23
In https://en.cppreference.com/w/c/language/_Static_assert, the single-argument _Static_assert form is marked since C23 and deprecated since C23. It should be marked since C11 instead.
- C11 does not allow omitting the message, while C23 permits it. Marking it as deprecated is because _Static_assert is no longer a keyword. --YexuanXiao (talk) 07:51, 31 January 2025 (PST)
[edit] llrintl in header
see it listed in the source, however my browser ( brave on linux ) doesn't show it on the page. 176.4.228.17 06:14, 1 February 2025 (PST)
- Are you referring to c/numeric/math/rint? --Ybab321 (talk) 02:47, 3 February 2025 (PST)
[edit] Typo, missing "the"
On https://en.cppreference.com/w/cpp/string/basic_string/resize_and_overwrite:
- This function performs following steps:
+ This function performs the following steps:
AhmadSamir (talk) 05:11, 3 February 2025 (PST)
[edit] Updates to clock()
In https://en.cppreference.com/w/c/chrono/clock, it says that the return value of clock() is (clock_t)(-1) "if that information is unavailable or its value cannot be represented." This is correct for C11 and earlier. But for C17 and later, when the value cannot be represented, clock() returns "an unspecified value". In particular, this permits an implementation to wrap around when it overflows.
The same applies to https://en.cppreference.com/w/cpp/chrono/c/clock for C++20 and later.
- Fixed for both C
clock
and C++std::clock
.✔ Done - The change was introduced by the resolution of DR 437. --Xmcgcg (talk) 00:59, 4 February 2025 (PST)
[edit] Aggregate initialization with brace-initialized temporary expressions
In the C++ Aggregate Initialization page, one of the cases is not listed: T{ arg1, arg2, arg3, ...}
if T
is an aggregate type. For example, std::array{ arg1, arg2 }
(with CTAD on C++17+).
- Aggregate init has the same syntax forms as list init, we should probably just remove the syntax forms from the aggregate init page --Ybab321 (talk) 10:07, 5 February 2025 (PST)
[edit] operator=, assign
should operator= and assign not be listed under Modifiers?
19:57, 6 February 2025 (PST)
- Makes sense, they do perform modifications, but operator= is a special member function and assign is basically the same operation, so there's some motivation for wanting to keep them with the ctor/dtor, which are also special member functions. Generally speaking, these are very arbitrary categorisations, I wouldn't spare too much attention to them --Ybab321 (talk) 04:05, 7 February 2025 (PST)
[edit] Github issue tracker
My unsolicited opinion is to combat vandalism, a github-based PR system can be used for edits. MDN is hosted on github and their issue tracker is much better than anything Mediawiki based (from experience). Obviously it would take a tremendous amount of work to port an entire wiki to github. But if cppreference were ever totally rehauled for some reason, it's an idea. Jxu (talk) 08:29, 7 February 2025 (PST)
- Ignoring general criticism towards git and/or github, doing something like that would remove the ability to preview the edits and I suspect is more effort than most people would be willing to contribute. That said, if you're interested in a Github based C++ documentation project that's welcoming contributers, I highly advise https://cpp-lang.net/docs/ --Ybab321 (talk) 09:33, 7 February 2025 (PST)
- I don't know what you mean by not being able to preview the edits. Pretty much anything in a PR is a preview. Actually I think it is less effort, because coders are much more likely to already have an existing github account than have an account here. If you mean PRs, yes the info has to be approved to be authoritative like MDN (which I consider a very good resource). But the ship has already sailed on this site long ago.
I took a look at the cpp-lang.net site, but it looks like almost a copy of cppreference. I don't understand what the "modern web technologies" are supposed to be. Jxu (talk) 18:45, 7 February 2025 (PST)
[edit] Description of DR CWG 2180 in Destructors is misleading
Correct behavior of DR CWG 2180 currently says "those destructors [referring to virtual destructors] are not called". That is not correct. I propose this change:
Behavior as published
the destructor of class X called the destructors for X's virtual direct base classes twice
(Added the word twice at the end).
Correct behavior
non-virtual destructors of direct base classes are called before corresponding virtual destructors
(That is, a complete rewrite of the section).
- “Those destructors” do not refer to virtual destructors. Virtual base classes are not related to virtual functions, they just share the virtual keyword. --Xmcgcg (talk) 17:27, 7 February 2025 (PST)
- Right, good catch! I still think it is misleading though and needs to be rephrased, however. The DR resolution is very clear, in my opinion, on that there previously was an ambiguity about destructors of direct virtual base classes being called more than once, and the fix is to clarify that destructors of non-virtual direct base classes are called, and then destructors of virtual direct base classes. I don't see how that can reasonably be interpreted as "those are not called" (i.e. never called, instead of exactly once as intended). Andebjor (talk) 20:06, 11 February 2025 (PST)
[edit] Wrong example for explicit object parameter
CRTP example from
https://en.cppreference.com/w/cpp/language/member_functions#Explicit_object_parameter
which is pasted below, is wrong because some_type::operator++ hides add_postfix_increment::operator++. Either, using declaration in some_type should be added, or some_type::operator++ should be replaced by non-meber function Here is the original example
// a CRTP trait struct add_postfix_increment { template<typename Self> auto operator++(this Self&& self, int) { auto tmp = self; // Self deduces to "some_type" ++self; return tmp; } }; struct some_type : add_postfix_increment { some_type& operator++() { ... } };
[edit] Error in example on std::remainder
In notes it says:
std::fmod, but not std::remainder
is useful for doing silent wrapping of floating-point types to unsigned integer types: (0.0 <= (y = std::fmod(std::rint(x), 65536.0)) ? y : 65536.0 + y) is in the range [
-0.0,
65535.0]
, which corresponds to unsigned short, but std::remainder(std::rint(x), 65536.0) is in the range [
-32767.0,
+32768.0]
, which is outside of the range of signed short.
There is a misplaced bracket, should be like this:
(0.0 <= (y = std::fmod(std::rint(x), 65536.0))) ? y : 65536.0 + y
[edit] since c23 below typeof
Add "since c23" below "typeof" in the first column of the table.
[edit] Add additional chrono example
I would like to suggest adding an example to the main chrono page that shows how to get the current time three different ways:
#include <chrono> #include <iostream> int main() { using namespace std; using namespace chrono; auto tp_utc = system_clock::now(); cout << "Current time UTC is : " << tp_utc << '\n'; cout << "Current time local is : " << current_zone()->to_local(tp_utc) << '\n'; cout << "Current time somewhere else is : " << locate_zone("Australia/Sydney")->to_local(tp_utc) << '\n'; }
The intent is to get an early view of two common functions (get system time and get local time) and show the connection to an often needed but rarely supplied (by other languages/libraries) extension to this basic functionality. To get the time somewhere else one often needs to change the computer's local time zone (a global), but not in chrono. I want to motivate the reader to learn more with this tutorial material that is not readily apparent from a reference of the specification.
Howardhinnant (talk) 17:42, 9 February 2025 (PST)Howardhinnant
- This is a reference site. I appreciate your motivation, but for an introduction of any part of the standard library, there needs to be a detailed article or video rather than a standalone example. --Xmcgcg (talk) 18:10, 9 February 2025 (PST)
- Perhaps it should be placed in cpp/chrono/tzdb/current_zone or cpp/chrono/time_zone/to_local instead, which seems more appropriate. I understand the chrono library has so much to cover, but cluttering the chrono main page with excessive content clearly isn't ideal. Maybe what we really need is a dedicated space hosting examples about standard C++- ideally one that enables cross-navigation with C++ Reference. --YexuanXiao (talk) 20:21, 9 February 2025 (PST)
- The couple of examples was added to suggested places: [1], [2] – I don't see any problem with adding concise, motivating, ready for copy-paste snippets, esp. suggested by Standard authors.) --Space Mission (talk) 07:41, 10 February 2025 (PST)
[edit] Want to provide examples for conditional operator page for some bullets
Conditional_operator
page.
Previous suggestion removed (it contains broken links and footnotes), it can still be found in the edit history.
If its hard to differentiate which examples are new, should I post differently, or is this way OK?
- I have just rearranged the section, so the previous TODO box does not apply anymore. You can suggest the examples based on each phase of determining the common type now. --Xmcgcg (talk) 19:42, 10 February 2025 (PST)
- Yeah its pretty confusing topic to leave it without examples. I also suggest replace previous example, that has this line: using T = const B;, at the end of stage 3, to more detailed one, because this part might be really confusing. Below I already wrote without it.
[edit] Stage 3
struct U { operator int&(); }; int i = 2; true ? i : U(); // reference binds directly to the result of the conversion, // target type is 'int&' struct S1 {} s1; struct S2 : S1 {}; true ? std::move(s1) : S2(); // reference binds directly to subobject, // target type is 'S1&&' // TY of 'const std::string' at least as cv-qualified as TX = std::string // target type is 'const std::string' true ? std::string{} : static_cast<const std::string>(std::string{}); struct A {}; struct B : A {}; using CA = const A; using CB = const B; true ? CA() : B(); // TY is 'const A' and cv-qualification of TX is '', // so target type is 'const A' true ? A() : CB(); // TY is 'A' and cv-qualification of TX is 'const', // so target type is 'const A' // notice: even though implicit conversion well-formed, // in stage 5 overload resolution will fail true ? std::string{} : "str2"; // type of Z is 'std::string', // even though none of the conversions were applied
[edit] Stage 4
true ? "123" : "456"; // both lvalues
[edit] Stage 5
struct A { operator int() const; }; struct B : A {}; using CB = const B; // at this stage CB() operand already converted to 'const A' true ? A() : CB(); // ?: yields prvalue of type 'int'
[edit] Stage 6
int i = 2; long j = 3; (true ? i : j)++; // error, ?: yields prvalue of 'long'; int* intPtr; using Mixed = decltype(true ? nullptr : intPtr); static_assert(std::is_same_v<Mixed, int*>); // nullptr becoming int* struct A { int* m_ptr; } a; int* A::* memPtr = &A::m_ptr; // memPtr is a pointer to member m_ptr of A // memPtr makes nullptr as type of pointer to member m_ptr of A static_assert(std::is_same_v<decltype(false ? memPtr : nullptr), int*A::*>); // a.*memPtr is now just pointer to int and nullptr also becomes pointer to int static_assert(std::is_same_v<decltype(false ? a.*memPtr : nullptr), int*>);
--Sneed Deens (talk) 05:55, 11 February 2025 (PST)
- The stage 3 example (as well as the current one in the operator page) should not use “target type”, “TX” or “TY” for the type of only one operand. Implicit conversions are attempted to be formed in both ways, so we need to state that one conversion would succeed and the other would fail in order to determine the result type. --Xmcgcg (talk) 18:18, 11 February 2025 (PST)
- Maybe a full explanation is actually needed, not sure if for all examples in stage 3, but I will provide for all:
struct U { operator int&(); }; int i = 2; int& ri = true ? i : U(); // from 'i' to type related to type 'U': // type of Z is 'U', so target type is 'U', // but implicit conversion sequence from type 'int' to type 'U' can't be formed // (e.g. because no converting constructor U(int&);) // // from 'U()' to type related to type 'int': // reference binds directly to the result of the conversion function, // so target type is 'int&', // implicit conversion sequence from type 'U' to type 'int&' can be formed // // exactly one conversion sequence can be formed, and it is applied to 'U()' operand, // at the end of whole process ?: yields lvalue of 'int' struct S1 {} s1; struct S2 : S1 {}; S1&& rs1 = true ? std::move(s1) : S2(); // from 'std::move(s1)' to type related to type 'S2': // type of Z is 'S2', so target type is 'S2', // but implicit conversion sequence from type 'S1&&' to type 'S2' can't be formed // // from 'S2()' to type related to type 'S1': // 'std::move(s1)' is xvalue, reference binds directly to S1 subobject, // so target type is 'S1&&', // implicit conversion sequence from type 'S2' to type 'S1&&' can be formed // // exactly one conversion sequence can be formed, and it is applied to 'S2()' operand, // at the end of whole process ?: yields xvalue of 'S1 struct Y {}; const Y cy = true ? Y() : static_cast<const Y>(Y()); // from 'Y()' to type related to type 'const Y': // 'const Y' at least as cv-qualified as 'Y', // so target type is 'const Y' // implicit conversion sequence from type 'Y' to type 'const Y' can be formed // // from 'static_cast<const Y>(Y())' to type related to type 'Y': // no conversion sequence is formed // // result is prvalue of 'const Y' struct A {}; struct B : A {}; using CA = const A; using CB = const B; const A ca1 = true ? CA() : B(); // from 'CA()' to type related to type 'B': // type of Z is 'B', so target type is 'B', // but implicit conversion sequence from type 'const A' to type 'B' can't be formed // // from 'B()' to type related to type 'const A': // TY is 'const A' and cv-qualification of TX is '', // so target type is 'const A', // implicit conversion sequence from type 'B' to type 'const A' can be formed // // exactly one conversion sequence can be formed, and it is applied to 'B()' operand, // at the end of whole process ?: yields prvalue of 'const A' const A ca2 = true ? A() : CB(); // error // from 'A()' to type related to type 'const B': // type of Z is 'const B', so target type is 'const B', // but implicit conversion sequence from type 'A' to type 'const B' can't be formed // // from 'CB()' to type related to type 'A': // TY is 'A' and cv-qualification of TX is 'const', // so target type is 'const A', // implicit conversion sequence from type 'const B' to type 'const A' can be formed // // even though implicit conversion well-formed // in later stage overload resolution will fail std::string str1 = true ? std::string{} : "str2"; // from 'std::string{}' to type related to type 'const char[5]': // type of Z is 'const char*' (array-to-pointer conversion applied), // so target type is 'const char*', // but implicit conversion sequence from type 'std::string' to type 'const char*' // can't be formed (std::string class doesn't have conversion function) // // from "str2" to type related to type 'std::string': // type of Z is 'std::string', so target type is 'std::string' // implicit conversion sequence from type 'const char[5]' to 'std::string' can be formed // // result is prvalue of 'std::string'
--Sneed Deens (talk) 10:07, 12 February 2025 (PST)
[edit] Typo on https://en.cppreference.com/w/cpp/standard_library
Under the "Names associated with safe functions in standard C" section:
If any C++ header is included, it is implementation-defined whether any of the following C standard Annex K names are declared in the global namespace (none of them are declared in namespace std)
Zstolfi (talk) 10:45, 10 February 2025 (PST)
- The wording is taken from the latest standard draft. --Xmcgcg (talk) 19:42, 10 February 2025 (PST)
- and before we run off to make a PR to fix it in the standard, https://english.stackexchange.com/questions/456276 and https://english.stackexchange.com/a/475030 and other discussions seem to agree that both "any of" and "none" can be followed by either singular or plural verbs. Though I agree 'are' sounds better to my mostly-american ear. --Cubbi (talk) 20:05, 10 February 2025 (PST)
[edit] suggestion for improvement https://en.cppreference.com/w/c/language/declarations
The example about a struct given on the page itself is not explained by the content of the page, but it is inferred that the type specifier struct is a struct declaration and it is worth clarifying this, which is not explicitly indicated, which justifies that a structure can be defined and then the declarators declared or simply use a forward declaration and add the declarators.
[edit] Wrong example in string literals
https://en.cppreference.com/w/cpp/language/string_literal#Concatenation
The given example "Hello, " " world!" results in a string literal with 2 consecutive spaces after the comma. The page shows only one space character after the comma, which is wrong.
- ✔ Done: fixed, danke.) --Space Mission (talk) 02:15, 13 February 2025 (PST)
[edit] NumericType is not only for valarray
The named requirement NumericType page states that it “Specifies that the type can be used as the template argument of std::valarray,” but that is not really true anymore. At least since C++23, std::complex
uses the requirement, too.
—Bolpat (talk) 05:44, 13 February 2025 (PST)
- ✔ Done: the std::complex's been added – it requires NumericType since C++98. --Space Mission (talk) 13:48, 13 February 2025 (PST)
[edit] utility/optional/operator_cmp Return value section not in correct order
For example, the top section has case 3 4 5 6 for operators < <= > >=, but the return value section has case 3 4 5 6 for operators < > <= >=. (Not exhaustive list, I did not go through every case)
Terencel (talk) 07:05, 13 February 2025 (PST)
[edit] Add example to std::formatter<std::chrono::duration>
std::formatter<std::chrono::duration> does not have an example. I would like to add the following example. But I get a message "editing of this page is temporarily disabled for new users"
#include <chrono> #include <format> #include <iostream> using namespace std::chrono_literals; int main() { std::chrono::seconds dur = 18243s; std::cout << std::format("Duration is {}\n",dur); std::cout << std::format("Duration is {:%T}\n",dur); std::cout << std::format("Duration is {:%H:%M:%S}\n",dur); std::cout << std::format("Duration is {:%H hours %M minutes %S seconds}\n",dur); }
Output:
Duration is 18243s Duration is 05:04:03 Duration is 05:04:03 Duration is 05 hours 04 minutes 03 seconds
Netjeff (talk) 13:09, 13 February 2025 (PST)
- ✔ Added with minimal changes (in-house formatting). Thanks.) --Space Mission (talk) 23:31, 13 February 2025 (PST)
[edit] Return type of c/string/byte/strtok
Suggestion for c/string/byte/strtok
I found this phrasing of strtok
return value confusing (attached below), as I thought it initially returned a pointer to next token or NULL, if there were no other token, even on the first run. But what actually happens is on the first call, it points to the first token, and each subsequent call points to the respective token.
"Returns pointer to the beginning of the next token or a null pointer if there are no more tokens."
I suggest the next correction:
"On the first call returns pointer to beginning of the first token, every subsequent call returns pointer to the beginning of the subsequent token. Returns a null pointer if there are no more tokens."
--Wspvlv (talk) 07:09, 16 February 2025 (PST)
[edit] c/language/auto "either" breaks grammar <C23
When setting "standard revision" on the navbar to anything below C23, the sentence structure is broken:
The auto keyword can be used as either a storage class specifier.
My suggestion:
The auto keyword can be used as a storage class specifier. It can also be used for type inference.(since C23)
Nat (talk) 07:12, 16 February 2025 (PST)
[edit] Incorrect statistics
https://en.cppreference.com/w/Special:Statistics Only two active users! Dmi3 (talk) 09:06, 16 February 2025 (PST)
[edit] new revision introduced miss leading self assignment handling in copy assignment
121.35.0.122 10:19, 16 February 2025 (PST)
The current revision of rule of five example by this edit:
```
20:20, 1 September 2024 YexuanXiao ,
```
introduces the million redundant tests for copy assignment (CppCoreGuidelines C.62) when handling self-assignment, which is miss leading.
Can the latest official version (7 June 2019) be recorved?
This official version is the only complete and correct example of rule of five, which is not even seen in `The C++ Programming Language` and `C++ Primer`.
Self assignment is covered in these two links:
```
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines ,
C.62: Make copy assignment safe for self-assignment:
https://isocpp.org/wiki/faq/assignment-operators ,
```
- Yes, the new version has a few issues and misses on a couple important points, rv'd --Cubbi (talk) 13:32, 16 February 2025 (PST)
[edit] unofficial archive (9 February 2025) is stained
121.35.0.122 21:46, 16 February 2025 (PST)
```
Yes, the new version has a few issues and misses on a couple important points, rv'd --Cubbi (talk) 13:32, 16 February 2025 (PST)
```
Thanks for bring the official version back.
Also that wrong edit went to the latest un-official (9 February 2025) archive, should we mark that archive as flawed?
Maybe we should lock down the ip and account of that edit. God knows what is its next step.
```
20:20, 1 September 2024 YexuanXiao ,
```
[edit] Adjusting line spacing
Greetings, I'm an occasional user of this site. I made an account because I have a suggestion on how the appearance can be improved.
One thing that is bothering me is how the line-height seems very small, which, in my opinion, makes it difficult to read -- the words look cramped. I am suggesting increasing it to, say, 1.5em.
I made a demo here: https://imgur.com/a/DBmGqVK
It's a small change, but I think it improves the readability of the site considerably. Eatmorepies (talk) 10:03, 17 February 2025 (PST)
[edit] default_arguments operators
https://en.cppreference.com/w/cpp/language/default_arguments
class C { int operator[](int i = 0); // ill-formed int operator()(int x = 0); // OK };
I believe operator[] is allowed to have default arguments since C++23. Taw3e8 (talk) 06:05, 18 February 2025 (PST)
[edit] Add escape sequence link
Could you please add an escape sequence page link next to string literal, otherwise it's really hard to find.
[edit] Dark mode please
Please add dark mode so that I can read the docs when I am in bed thinking about how to fix a bug.
2409:40D5:1075:8266:2924:F186:D719:B27C 06:16, 19 February 2025 (PST)
[edit] Updating the C++26 compiler support page
It seems that the P1061 Structured bindings can introduce a pack proposal, which has entered C++26, has been implemented in Clang 21. (See https://github.com/llvm/llvm-project/pull/127980) Also we should add <contracts> and <hive> to the new headers section. Nofe1248 (talk) 18:37, 20 February 2025 (PST)
[edit] Add an escape sequence link to the c/language page
Can you add an escape sequence link next to the String literals in the c/language page, because it is difficult to find.
[edit] std::align example UB Follow Up
After CWG 2489, an array of char
no longer implicitly creates objects within the storage region it occupies. Due to this change, along with the rules outlined in [basic.lval/11] mentioned by Seha in their suggestion, the current example exhibits undefined behavior.
The suggestion provided by Seha, that is introducing placement new
is a valid resolution. However, the root cause of the issue may not be immediately apparent, as it stems from the use of an array of char
instead of std::byte
.
To clarify this, I propose modifying the example as follows:
#include <iostream> #include <memory> template<std::size_t N> struct MyAllocator { // After CWG 2489, arrays of char do not implicitly create objects. std::byte data[N]; void* p; std::size_t sz; MyAllocator() : p(data), sz(N) {} // Allocates T at an a-byte boundary, but does not use placement new // Only safe for implicit-lifetime types template<typename T> T* implicit_aligned_alloc(std::size_t a = alignof(T)) { if (std::align(a, sizeof(T), p, sz)) { T* result = reinterpret_cast<T*>(p); p = static_cast<std::byte*>(p) + sizeof(T); sz -= sizeof(T); return result; } return nullptr; } }; struct Foo { Foo() {}; Foo(const Foo& f) = delete; // Not an implicit-lifetime type }; int main() { MyAllocator<64> a; std::cout << "allocated a.data at " << (void*)a.data << " (" << sizeof a.data << " bytes)\n"; // Allocate a char if (char* p = a.implicit_aligned_alloc<char>()) { *p = 'a'; std::cout << "allocated a char at " << (void*)p << '\n'; } // Allocate an int if (int* p = a.implicit_aligned_alloc<int>()) { *p = 1; std::cout << "allocated an int at " << (void*)p << '\n'; } // Allocate an int, aligned at a 32-byte boundary if (int* p = a.implicit_aligned_alloc<int>(32)) { *p = 2; std::cout << "allocated an int at " << (void*)p << " (32-byte alignment)\n"; } // UB: Foo is not an implicit-lifetime type, so the following is invalid. // if (Foo* p = a.implicit_aligned_alloc<Foo>()) // { // *p = Foo{}; // std::cout << "allocated a Foo at " << (void*)p << '\n'; // } }
Jellyboi (talk) 08:20, 21 February 2025 (PST)
- char->byte is a good minimal change; but I think the example should keep focus on the call to align and what it returned, so the extra 10 lines demonstrating something else might be diluting too much (but I left a comment about implicit-lifetime and the rename implicit_aligned_alloc rename is very good) --Cubbi (talk) 14:46, 24 February 2025 (PST)
[edit] Text makes no sense
https://en.cppreference.com/w/cpp/experimental/unique_resource/make_unique_resource_checked
> Creates a unique_resource, initializes its stored resource handle is initialized with std::forward<R>(r) and its deleter with std::forward<D>(d).
Should read
> Creates a unique resource, initializes its stored resource handle with std::forward<R>(r) and its deleter with std::forward<D>(d).
86.150.195.248 09:05, 22 February 2025 (PST)
[edit]
The example on the cpp/container/flat map/extract page does not compile due to some typos, even when using a compiler that supports std::flat_map and std::println.
- The extract function is rvalue ref-qualified, so line 12 of the example fails to compile. The map should probably be moved before calling extract.
- auto c = map.extract(); → auto c = std::move(map).extract();
- There are two typos in line 21 of the example:
- c.value → c.values
- std::vector<int> → std::vector<double>
These typos are also present on the following pages:
- cpp/container/flat set/extract
- cpp/container/flat multiset/extract
- cpp/container/flat multimap/extract
A fixed version of the code can be found here: [25] (with std::println replaced by fmt::println). Mzubor (talk) 14:49, 23 February 2025 (PST)
[edit] dynamic_cast, explanation of downcast wrong
Hi, On the dynamic_cast page https://en.cppreference.com/w/cpp/language/dynamic_cast , paragraph "e)" of the explanation I think there's a mistake:
If target-type is “reference to (possibly cv-qualified) Base” and the type of expression is “(possibly cv-qualified) Derived” such that Base is a base class of Derived, the result is the unique Base subobject of the Derived object referred to by expression.[2]
should be (switched placed between "Derived" and "Base"):
If target-type is “reference to (possibly cv-qualified) Derived” and the type of expression is “(possibly cv-qualified) Base” such that Base is a base class of Derived, the result is the unique Base subobject of the Derived object referred to by expression.[2]
207.45.249.138 01:51, 25 February 2025 (PST) nicu@damaschin.de
- no, that paragraph describes casting from derived to base. Casting from base to derived is described lower, but I agree it's really hard to read that section (I made some edits to it to add/highlight simpler terms) --Cubbi (talk) 06:40, 25 February 2025 (PST)
[edit] condition_variable relock is not atomic
Quoting from cpp/thread/condition_variable:
> Call wait, wait_for, or wait_until on the std::condition_variable (atomically releases the mutex and suspends thread execution until the condition variable is notified, a timeout expires, or a spurious wakeup occurs, then atomically acquires the mutex before returning).
The mutex is not actually relocked atomically (whatever that means). This is not required by the standard, and glibc pthread (to which libstdc++ and libc++ delegate) acquires it normally. It may be held by a different thread when the notification arrives, or another thread may obtain it between the OS wakeup and wait() locking. This can make the exit condition false even if the wakeup is non-spurious. Abgkxmbg (talk) 13:07, 25 February 2025 (PST)
- the standard wording is here: https://eel.is/c++draft/thread.condition#general-3 --Cubbi (talk) 14:21, 25 February 2025 (PST)
[edit] Expanding std::formatter page
I think the example given in cpp/utility/format/formatter is not very informative because it does not provide information about what the ParseContext and FmtContext templates are or can do (for example, there is no mention of advance_to and forward formatting), and it is not similar to the common cases where you want to make a type formatable, so it is not as clear and useful as it could be either.
Here is an additional example proposal that could be added:
#include <iostream> #include <cassert> #include <format> #include <cmath> #include <print> struct Vector2f { float x{}, y{}; Vector2f(float x, float y) : x(x), y(y) {} std::pair<float, float> AsPolar() const { return { std::hypotf(x, y), std::atan2f(y, x) }; } }; template<class charT> class std::formatter<Vector2f, charT> { enum class FormatType { Point, PolarRad, PolarDeg }; FormatType _formatType = FormatType::Point; std::formatter<float, charT> _formatterX; std::formatter<float, charT> _formatterY; public: template<class ParseContext> constexpr ParseContext::iterator parse(ParseContext& ctx) { auto it = ctx.begin(); if (it == ctx.end()) return it; switch (*it) { case 'P': _formatType = FormatType::Point; it++; break; // P is default case 'R': _formatType = FormatType::PolarRad; it++; break; case 'D': _formatType = FormatType::PolarDeg; it++; break; } if (it == ctx.end() || *it != '{') return it; ctx.advance_to(it + 1); it = _formatterX.parse(ctx); if (*it != '}') throw std::format_error("Ill-formed expression. '}' expected."); it++; if (it == ctx.end() || *it != '{') { // If just one formatter is specified, it will be used for both x and y. _formatterY = _formatterX; return it; } ctx.advance_to(it + 1); it = _formatterY.parse(ctx); if (*it != '}') throw std::format_error("Ill-formed expression. '}' expected."); return ++it; } template<class FmtContext> FmtContext::iterator format(const Vector2f& v, FmtContext& ctx) const { float x{}, y{}; std::string_view suffix; switch (_formatType) { case FormatType::Point: x = v.x; y = v.y; break; case FormatType::PolarRad: std::tie(x, y) = v.AsPolar(); suffix = "rad"; break; case FormatType::PolarDeg: std::tie(x, y) = v.AsPolar(); y *= 180.0f / std::numbers::pi_v<float>; suffix = "deg"; break; default: throw std::format_error("Invalid format type for Vector2f."); } auto out = ctx.out(); out = std::format_to(out, "("); out = _formatterX.format(x, ctx); out = std::format_to(out, ", "); out = _formatterY.format(y, ctx); out = std::format_to(out, "{})", suffix); return out; } }; int main() { std::println("{0:P} is the same as {0:D} and {0:R}", Vector2f{3, 4}); std::println(""); std::println("{0:P} is approx. the same as {0:D{<3}{>5.2f}} and {0:R{^5.2}}", Vector2f{12, 5}); return 0; }
Output:
(3, 4) is the same as (5, 53.1301deg) and (5, 0.9272952rad) (12, 5) is approx. the same as (13 , 22.62deg) and ( 13 , 0.39 rad)
[edit] 96 to 99 character set expansion
https://en.cppreference.com/w/cpp/language/charset incorrectly states that the expansion of the basic character set to 99 characters is from C++26. It is in fact from C++23, but I cannot edit the page. Neilb (talk) 09:22, 2 March 2025 (PST)
- ✘ No change required: “Dollar Sign” $, “Commercial At” @, and “Grave Accent” ` are C++26 extensions. You may re-check it in C++26 compare support table and by the date of the feature proposal P2558R2. --Space Mission (talk) 12:03, 2 March 2025 (PST)
[edit] Suggestion Destructor Parameters
I suggest that on the Destructor page, in the Syntax section, that the "parameter-list" be removed. [[26]] 2404:C0:5C10:0:0:0:459:C47B 00:34, 3 March 2025 (PST)
[edit] vector::resize refers to pre-LWG2160 behavior
https://en.cppreference.com/w/cpp/container/vector/resize
> Notes > Vector capacity is never reduced when resizing to smaller size because that would invalidate all iterators, rather than only the ones that would be invalidated by the equivalent sequence of pop_back() calls.
The only other mentions of pop_back are in the defect report sections. Should be changed to, for example, "rather than only the ones that point beyond the new end", or something more formal.
--155.4.132.39 01:10, 4 March 2025 (PST)
[edit] Change keyword "not" to "!"
On page cpp/container/vector/pop_back, in the example we have: "while (not numbers.empty())
". The keyword "not
" should be changed to "!
":
while (!numbers.empty())
FERcsI (talk) 23:29, 4 March 2025 (PST)
{ {include page|cpp/container/pop_back|vector}}
[edit] std::align example still requires std::launder
I believe the recent modification to be still insufficient. I believe that T* result = reinterpret_cast<T*>(p); should actually be T* result = std::launder(reinterpret_cast<T*>(p)); to allow the current example to work. This adjustment is necessary because the current example does not produce a pointer to the suitable created object, as described here (unlike std::malloc for example). To correctly obtain a pointer to the implicitly created object, std::launder is required. -- Jellyboi (talk) 04:21, 5 March 2025 (PST)
- std::launder requires an object to exist at the memory address being laundered, so it's of no use here IIUC (which I don't, only liars claim to understand std::launder >_>;). Probably placement new is required if we can't find a way to invoke magic implicit object creation --Ybab321 (talk) 04:58, 5 March 2025 (PST)
- From what I understand, for the new example, the implicit object creation is invoked, hence an object does exist at the memory address being laundered, it's just that we require the pointer to point to this object, hence the necessity of std::launder, similar to this question. -- Jellyboi (talk) 07:31, 5 March 2025 (PST)
- Oh I see, a the mere creation of a std::byte array is enough to trigger implicit lifetime object creation. Are we sure that T* result doesn't point at this implicitly created object? The cast-from-void rules only requires that p points to a T object. The "suitable created object" term is very strange to me, it produces a pointer to an object if it's not UB to do so, otherwise it's UB? I'm not sure it really means anything, and I don't see anything in the spec refer back to this term...
- I'm mostly going off the intuition that the implicit lifetime stuff was intended to support the "natural" C semantics of hacking byte buffers as well-defined behaviour, so I'm overall a little sceptical that we need std::launder here for that reason --Ybab321 (talk) 03:54, 6 March 2025 (PST)
- I believe the term 'suitable created object' means if producing a pointer to such an object can lead to a program that has no UB, it will perform it, otherwise it doesn't. However, I think the main issue is that the operations that produce a pointer to a suitable created object only includes operations such as std::malloc, std::calloc etc. This suggests that reinterpret_cast alone may not be sufficient. Furthermore, with the cast-from-void rules you mentioned, it requires pointer-interconvertibility, which is not the case between the int and char.
- The way I thought about this is that this is similar to placement-new in a std::byte array, where if we used the pointer to the array itself to try to refer to the new object, it is likely that we require std::launder unless the original object is transparently replaceable by the new object (but that's beside the point). However, it would be helpful to have someone more knowledgeable weigh in on this, as I only have limited knowledge on the standard itself :). It’s worth confirming, as I’ve seen this pattern used in treating C++ as "C with classes," which could introduce UB into codebases, and I think cppreference having a comment regarding uses like this would be good. Thanks! -- Jellyboi (talk) 04:54, 6 March 2025 (PST)
- From what I understand, for the new example, the implicit object creation is invoked, hence an object does exist at the memory address being laundered, it's just that we require the pointer to point to this object, hence the necessity of std::launder, similar to this question. -- Jellyboi (talk) 07:31, 5 March 2025 (PST)
Concerning the pointer interconvertibility, I think you're right. The "the original pointer value represents the address A of a byte in memory" is a std::byte*, as it's assigned by std::align as "an adjusted value of [the argument] ptr
", which itself originally comes from [the decayed value of] data in the constructor, and pointer-interconvertibility is not happy with std::byte* -> T*. That means the result of the reinterpret_cast is "unchanged", and so result is a pointer (of type T*) that refers to the (first) std::byte that holds the storage of the implicitly created object. Then the question is, can you access this pointer of type T*? I believe that question is answered by the type accessibility rules. The dynamic type of the object is T (due to the implicit object creation), and the "T_ref
" type is std::byte. So in the end, I think this all works out as-is, and the pointer-inconvertibility bit of the cast-from-void rules was bit of a red herring.
Sorry to make you read all this btw! And thanks for raising the issue --Ybab321 (talk) 06:55, 6 March 2025 (PST)
- Thanks for the reply! I'm not sure if there's a more convenient place to continue this discussion, but I'll leave a comment here for now. I still disagree with the current explanation for the following reasons:
- First, let's examine the assumption that the dynamic type of the object is T. The issue is that the pointer does not point to an object of type T. In our example, it points to an object of dynamic type std::byte. While the two objects exist at the same memory address, the pointer still refers to the std::byte object. The only way it can come to refer to another object is via pointer-interconvertibility rules, std::launder, or transparently replaceable rules.
- Now, what is T_ref in our case? Since we are performing a reinterpret_cast to T*, T_ref must be T itself. The example char* p2 = reinterpret_cast<char*>(&i); from here illustrates this point clearly. Based on this, it follows that the type accessibility rule from here is not satisfied.
- Finally, consider my argument that the pointer still refers to the original object rather than the implicitly created one. I feel like it may be beneficial to consider the behavior of placement new - if the pointer automatically referred to the new object, there would be no need for the transparently replaceable rules, which explicitly dictate when a pointer is considered to refer to the new object.
- Apologies for the long post, but I hope this clarifies my perspective. If further discussion is needed, we might want to move to another platform to keep things manageable. Thanks for taking the time to read this! I really appreciate it! -- Jellyboi (talk) 10:05, 6 March 2025 (PST)
- Having consulted with a couple different people, it appears you're absolutely right. The main thing I had wrong in my head was the notion of "dynamic type", which I thought referred to the last created thing in a buffer, and which I thought didn't violate strict aliasing because one of the aliasing paths is througuh std::byte. It's quite clear to me now that std::launder is required as suggested, and that means C compatible byte buffer hacking still isn't fully supported in C++ (at least until P3006). Again thanks for bringing this up, I'll go edit the example soon --Ybab321 (talk) 16:40, 13 March 2025 (PDT)
- std::launder has been added ✔ Done.
- Not sure if there's any reason we're not using the more straight-forward placement new / std::construct_at here, which would support non implicit lifetime types... --Ybab321 (talk) 16:52, 13 March 2025 (PDT)
- Thanks for looking into the issue, I really appreciate it! I originally suggested this particular fix (instead of std::construct_at) to highlight a potential mistake for those who still approach C++ in a C-style manner with classes. However, looking back, it might be better to encourage users to use std::construct_at instead, since as you said, it work with those that are not implicit-lifetime typed and this may become unnecessary if P3006 is accepted (which I recently learned about). That said, I still think this example provides valuable insight, so thanks again for the update! -- Jellyboi (talk) 05:03, 15 March 2025 (PDT)
- Having consulted with a couple different people, it appears you're absolutely right. The main thing I had wrong in my head was the notion of "dynamic type", which I thought referred to the last created thing in a buffer, and which I thought didn't violate strict aliasing because one of the aliasing paths is througuh std::byte. It's quite clear to me now that std::launder is required as suggested, and that means C compatible byte buffer hacking still isn't fully supported in C++ (at least until P3006). Again thanks for bringing this up, I'll go edit the example soon --Ybab321 (talk) 16:40, 13 March 2025 (PDT)
[edit] Syntax error in "Allocates memory for an objects"
Should be Allocates memory for object(s). https://en.cppreference.com/w/cpp/memory/shared_ptr/allocate_shared
[edit] Add condition to "Deleted default constructor"
In the "Deleted default constructor" section on the Default constructors page I think it would be helpful to add a condition for a specific case of union types.
From section "11.4.5.2 Default constructors" in the N4950 revision of the spec (C++23):
- 2 A defaulted default constructor for class X is defined as deleted if:
- (2.1) — X is a union that has a variant member with a non-trivial default constructor and no variant member of X has a default member initializer
This is detail that is missing from the Union declaration page, which just points to separate documentation on special member functions:
- If a union contains a non-static data member with a non-trivial special member function, the corresponding special member function of the union may be defined as deleted, see the corresponding special member function page for details.
Having this information present on the Default constructors page would have been helpful to me. I would expect this page to cover this specific case, since it already has some conditions that are specific to union types.
Thank you!
--Berlinquin (talk) 06:22, 7 March 2025 (PST)
- This condition was removed in June 2023 by the resolution of CWG issue 1353. --Xmcgcg (talk) 08:43, 7 March 2025 (PST)
- Interesting, thank you for link. Does this mean that this condition will be removed as of C++26? This is still information that I would have found helpful, though I guess it would belong with the conditions in the "Deleted default constructor" section marked (until C++26). --Berlinquin (talk) 09:03, 7 March 2025 (PST)
Does this mean that this condition will be removed as of C++26?
[edit] wrong padding value in example / substitution function for double round
in https://en.cppreference.com/w/c/numeric/math/round
IMHO in the example "The double version of round
behaves as if implemented as follows: ... "
the padding value 0.5 needs to be replaced by 0.49999999999999994,
else exact this value, the nextafter below 0.5, would erroneously be rounded up
reg. 'snap to' or 'pre-rounding in range change', which it isn't in the library
function 'round'. It also avoids erroneous snap-to roundup of e.g. 4503599627370497
which also doesn't occur with the library function.
[edit] std::exchange - Risky when using for move assignment operators.
Hello qualified cppreference editors! I'm a big fan of your work.
On the page for std::exchange (https://en.cppreference.com/w/cpp/utility/exchange) there is a note about using this function for move assignment operators and move constructors and there is an example struct S that demonstrates this. I would submit that std::exchange is wonderful for move constructors, but dangerous for move assignment operators.
Consider the example code from the article:
struct S { int n; S(S&& other) noexcept : n{std::exchange(other.n, 0)} {} S& operator=(S&& other) noexcept { // Careful! We "leak" if n is non-zero here; consider std::swap(n, other.n); n = std::exchange(other.n, 0); // Move n, while leaving zero in other.n // (note: in self-move-assignment, n is unchanged) return *this; } };
The example code uses an opaque int value for the exchanged data, so we can't really say that it's "incorrect". However, the code above (or the pattern anyway) "leaks" in cases where the data being exchanged represents an allocated resource (e.g., memory, file, socket, etc.).
For move assignment, if one wants to use std::exchange they'd first need to release the current resource first and then call std::exchange using the "invalid" value. Alternately, one could replace the std::exchange call with a std::swap call to ensure that the newly-moved resource is released during the destruction of the likely-soon-to-be-deleted temporary being moved from.
This clearly isn't an issue for move construction because the being-constructed object has no resource yet, so std::exchange is perfect in that case.
PunkFloyd (talk) 15:11, 10 March 2025 (PDT)
- we do discuss non-class resource handlers at some length in cpp/language/rule_of_three which, indeed, uses exchange in move-ctor but swap in move-assignment. It's worth a note/link in the exchange's page, I agree. --Cubbi (talk) 20:06, 10 March 2025 (PDT)
[edit] Invalid example
Modified example shows the issue:
#include <cstddef> #include <iostream> #include <memory> #include <memory_resource> #include <vector> class Value { int i; public: Value(int i) : i(i) { std::cout << "Value(), i = " << i << '\n'; } ~Value() { std::cout << "~Value(), i = " << i << std::endl; } void print() const { std::cout << "i = " << i << std::endl; } }; // Create a polymorphic allocator using the monotonic buffer resource std::byte buffer[sizeof(Value) * 18]; std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); std::vector<std::shared_ptr<Value>> test() { // SIGSEGV if those `resource` and `buffer` are used // // Create a polymorphic allocator using the monotonic buffer resource // std::byte buffer[sizeof(Value) * 18]; // std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); std::pmr::polymorphic_allocator<Value> allocator(&resource); std::vector<std::shared_ptr<Value>> v; for (int i{}; i != 4; ++i) // Use std::allocate_shared with the custom allocator v.emplace_back(std::allocate_shared<Value>(allocator, i)); return v; } int main() { auto v{test()}; auto v2{test()}; std::cout << "After.." << std::endl; for (const auto& sp : v) sp->print(); for (const auto& sp : v2) sp->print(); }
--45.95.218.138 08:07, 12 March 2025 (PDT)ZB
- ✔ Done. The error arises from the fact that the (commented out) buffer is local for
test()
, while thetest()
returns an object that uses that local buffer.) --Space Mission (talk) 09:13, 12 March 2025 (PDT)
[edit] libc++ support for is_invocable
and invoke_result
cpp/compiler support/17 does not specify the version of libc++ that introduced is_invocable
and invoke_result
. I believe they are first added in libc++ 6. ud2 (talk) 09:44, 12 March 2025 (PDT)
- Indeed, clang's status page only marks the P0604R0 as "Complete". Could you provide any link/proof? --Space Mission (talk) 14:39, 12 March 2025 (PDT)
[edit] Lambda capture [this] captures a pointer-by-value, not a reference
This line on the lambdas page is incorrect:
"7) simple by-reference capture of the current object"
The line implies that a capture like [this](){} is capturing the current object by reference. What is actually happening is that a copy of the this pointer is being captured by value.
Recommended change:
"7) simple by-copy capture of the pointer to the current object"
This is unlikely to be confused with copying the object itself by value, because 7) and 8) together would now read:
7) simple by-copy capture of the pointer to the current object 8) simple by-copy capture of the current object
50.198.212.225 14:08, 13 March 2025 (PDT) Danny Kumpf
- The standard makes an explicit point that capturing this does not capture by value. Though informally it is true that any capture by reference could probably be considered equivalent to a capture by value of a pointer to that variable --Ybab321 (talk) 16:20, 13 March 2025 (PDT)
[edit] Incorrect example in cpp/language/attributes/no unique address
--Regular8 (talk) 13:35, 15 March 2025 (PDT)At the end of the example provided on this page, it is stated that (sizeof(W) == 2), which is incorrect. It should be 3. Please fix :-)
- ✔ Done @ Example:) --Space Mission (talk) 16:53, 15 March 2025 (PDT)
[edit] hive is a redlink
Cppreference talk:FAQ is protected so I'm posting here.
on {{main page cpp contents}} (and Containers library) there's a link for cpp/container/hive and it says (C++26), but that page doesn't exist.
Rusty Cat (talk) 17:28, 17 March 2025 (PDT)
[edit] Link to enumerate_view from iota_view
I was looking for enumerate_view but I couldn't remember what it was called, I could only remember iota and iota_view. Linking between these pages in the "See also" section of each might be helpful?
[edit] imprecise datatype naming in SeeAlso of strtol
In: https://en.cppreference.com/w/c/string/byte/strtol
the "See Also"s read as "converts xxx to an ( unsigned ) integer",
IMHO it should be "converts xxx to a ( unsigned ) long or long long integer". 176.4.182.192 14:08, 20 March 2025 (PDT)
[edit] imprecise datatype naming in SeeAlso of strtol
In: https://en.cppreference.com/w/c/string/byte/strtol
the "See Also"s read as "converts xxx to an ( unsigned ) integer",
IMHO it should be "converts xxx to a ( unsigned ) long or long long integer". 176.4.182.192 14:09, 20 March 2025 (PDT)
[edit] [Typo] cpp/language/constraints
The first sentence on page cpp/language/constraints has a typo – "Class templates, function templates (include generic lambdas)..." should instead read "...(including generic lambdas)...".
NextDoorTech (talk) 16:11, 22 March 2025 (PDT)
- ✔ Done.) --Space Mission (talk) 16:52, 22 March 2025 (PDT)
[edit] 5) a) mixes up target_type and expression
5) a) should say
See the equivalent in the standard https://eel.is/c++draft/expr.dynamic.cast#8 which uses T which is the equivalent of target_type and not v, which is the equivalent of expression.
[edit] Suggestion to add ThorVG Project to Graphics category
Hello, I'd like to suggest to add ThorVG(https://www.thorvg.org/) project in Graphics Category. Can help this?
Library | Description | License | Configuration |
---|---|---|---|
ThorVG | Thor Vector Graphics is a lightweight portable library used for drawing vector-based scenes and animations including SVG and Lottie. It can be freely utilized across various software platforms and applications to visualize graphical contents. (Src) | MIT | conan, meson, msys2, vcpkg |
- ✔ Done. Cool, it's been added here.) --Space Mission (talk) 14:47, 27 March 2025 (PDT)
[edit] Typo in "class property specifiers"
cpp/language/class property specifiers#Eligibility for replacement's third bullet point has duplicated text:
- overload resolution fails or selects a deleted constructor when direct-initializing an object of type
C
from an xvalue of type of typeC
(emphasis added)
Please fix please fix. :-) --Adam B. Norberg (at work) (talk) 17:22, 27 March 2025 (PDT)
- ✔ Done: fixed.-) --Space Mission (talk) 18:01, 27 March 2025 (PDT)
[edit] cpp/iterator/reverse iterator/base
[edit] Notes
The base iterator refers to the element that is next (from the iterator_type
perspective) to the element the reverse_iterator
is currently pointing to. That is &*(this->base() - 1) == &(*this).
--Wondertx (talk) 05:10, 29 March 2025 (PDT)
[edit] Example for mbrtoc16 handles case -2 incorrectly
https://en.cppreference.com/w/cpp/string/multibyte/mbrtoc16
Instead of `if (rc == (std::size_t) - 2) break;`, `if (rc == (std::size_t) - 2) continue;` prior to `std::cout << "Next UTF-16 char: "` would be the correct action as both `c16` is in an undefined state in this case, as well the fact that `state` still has state buffered that requires more input.
This bug would be more clear if `mbrtoc16` was called with `n=1` or `n=2` as `rc == -2` is then reached repeatedly.
It also didn't handle the case `rc == 0` correctly either, as in this case `ptr += 1` would be necessary to advance past a consumed (and yielded) nullbyte.
2A02:810D:8C89:AA00:3962:23BA:A89E:EEAF 06:03, 31 March 2025 (PDT)
- ✔ Fixed. Danke.) --Space Mission (talk) 07:07, 31 March 2025 (PDT)
[edit] Mention that explicit specialization cannot have a `static` specifier
By the sentence "Explicit specialization may be declared in any scope where its primary template may be defined" in https://en.cppreference.com/w/cpp/language/template_specialization, it's easy to misinterpret that the following code works:
class C { public: template<int num> inline static int i = 0; template<> inline static int i<1> = 1; };
but since `static` is not allowed for explicit template specialization, it'll fail to compile(though clang and msvc just give warnings instead of errors). You should do this instead:
class C { public: template<int num> inline static int i = 0; }; template<> inline int C::i<1> = 1;
I'm not sure because it says 'where its primary template may be """defined"""', and a class is not fully defined inside itself, it's technically saying that you can't declare explicit specializations of the member templates inside the class, but the following code works just fine.
class C { public: template<int num> void f(); template<> void f<1>(); };
... except gcc gives an error, which I don't think it should, reading `template<> struct B<int*> {}; // OK via CWG 727: full specialization` in https://en.cppreference.com/w/cpp/language/member_template. (A bug report already exists: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85282)
Yeshjho (talk) 13:29, 31 March 2025 (PDT)
[edit] Wrong condition for basic_string allocator swap
If std::allocator_traits<Allocator>::
propagate_on_container_swap::value &&
get_allocator() == s.get_allocator() is false, the behavior is undefined.
Should be:
If std::allocator_traits<Allocator>::
propagate_on_container_swap::value ||
get_allocator() == s.get_allocator() is false, the behavior is undefined.
- ✔ Done by copying the wording from cpp/container/vector/swap. --D41D8CD98F (talk) 18:02, 1 April 2025 (PDT)
[edit] Fix std::void_t example
Hello cppreference admins -
The first example in https://en.cppreference.com/w/cpp/types/void_t does not work as intended.
"typename T::type" needs to be changed to "decltype(T::type)", please see the code below.
I do not have permission to edit the page since I just created my account but I have used cppreference for several years.
// primary template handles types that have no nested ::type member: template<class, class = void> struct has_type_member : std::false_type {}; // specialization recognizes types that do have a nested ::type member: template<class T> struct has_type_member<T, std::void_t<decltype(T::type)>> : std::true_type {};
I tested with g++ 11.2.1 using the --std=c++17 and --std=c++20 command line parameters
[edit] Example
#include <iomanip> #include <iostream> #include <type_traits> struct A { int type {}; }; template <class, class = void> struct has_type_member : std::false_type {}; template <class T> struct has_type_member<T, std::void_t<decltype(T::type)>> : std::true_type {}; int main() { std::cout << std::boolalpha << "has_type_member<A>::value == " << has_type_member<A>::value << '\n'; }
Output:
has_type_member<A>::value == true
P.S. - I feel an example using variable templates would be better, like the "is_iterable" example on the same page.
// primary variable template handles types that have no nested ::type member: template<class, class = void> constexpr bool has_type_member = false; // specialization recognizes types that do have a nested ::type member: template<class T> constexpr bool has_type_member<T, std::void_t<decltype(T::type)>> = true;
[edit] Example
#include <iomanip> #include <iostream> #include <type_traits> struct A { int type {}; }; template <class, class = void> constexpr bool has_type_member = false; template <class T> constexpr bool has_type_member<T, std::void_t<decltype(T::type)>> = true; int main() { std::cout << std::boolalpha << "has_type_member<A> == " << has_type_member<A> << '\n'; }
Output:
has_type_member<A> == true
Thanks,
Jeffryklew (talk) 07:58, 3 April 2025 (PDT) Jeffry Lew
- The intention of the first example is not to detect a data member named
type
, but a nested type. This is demonstrated in the runnable example code via theiterator_trait
class template --Ybab321 (talk) 09:07, 3 April 2025 (PDT)
[edit] Suggested Change in Example of Compound Literals
In the notes section at the end of the page, there exists an example
int f(void) { struct s {int i;} *p = 0, *q; int j = 0; again: q = p, p = &((struct s){ j++ }); if (j < 2) goto again; // note; if a loop were used, it would end scope here, // which would terminate the lifetime of the compound literal // leaving p as a dangling pointer return p == q && q->i == 1; // always returns 1 }
If you would look at the 6th line, there exists an expression p = &((struct s){j++}); Above line produces error since there exists no address for the compound literal that p is trying to store as compound literals exists on stack i.e. temporary.
Suggested change: *p = ((struct s){j++});
Reference: https://en.cppreference.com/w/c/language/compound_literal Tag: @rinz0x0cruz
The MediaWiki formatting was applied by --Space Mission (talk) 05:40, 5 April 2025 (PDT)
- × The example was reformatted and it works (see the C page). In fact, it was borrowed from the C standard (e.g., N3096, p.79). The nameless compound literal though being created on stack nonetheless has an address (the “materialization” of a temporary in this case happens since its address is taken), whereas *p in your suggestion does not have an associated storage. --Space Mission (talk) 05:40, 5 April 2025 (PDT)
[edit] std::deque's push_front sample output is incorrect
Title. The sample output says the deque will contain "send" "me" in that order after the two operations, but running the code proves otherwise.
- ✔ Fixed. Thanks. --Space Mission (talk) 00:58, 6 April 2025 (PDT)
[edit] std::map doesn't document that its nodes/values are stable
It would be desirable to mention that std::map's values are stable, and pointers to the value nodes can be used even after insertion/deletion of other nodes:
Section 23.1.2#8 (associative container requirements):
"The insert members shall not affect the validity of iterators and references to the container, and the erase members shall invalidate only iterators and references to the erased elements."
````
- I think I agree; while this is scattered in bits across the pages like cpp/container/map/insert and cpp/container/map/erase, we don't have it in cpp/named_req/AssociativeContainer (the logical place for https://eel.is/c++draft/associative.reqmts#general-175 whose old revision you quoted) and stability is a headline feature that deserves a spot on the top-level page like it already has in cpp/container/list --Cubbi (talk) 09:55, 9 April 2025 (PDT)
[edit] Correct example implementation on cpp/algorithm/ranges/contains
Removing the unnecessary `std::move` from the second overload.
contains (1,2) |
---|
struct __contains_fn { template<std::input_iterator I, std::sentinel_for<I> S, class Proj = std::identity, class T = std::projected_value_t<I, Proj>> requires std::indirect_binary_predicate<ranges::equal_to, std::projected<I, Proj>, const T*> constexpr bool operator()(I first, S last, const T& value, Proj proj = {}) const { return ranges::find(std::move(first), last, value, proj) != last; } template<ranges::input_range R, class Proj = std::identity, class T = std::projected_value_t<ranges::iterator_t<R>, Proj>> requires std::indirect_binary_predicate<ranges::equal_to, std::projected<ranges::iterator_t<R>, Proj>, const T*> constexpr bool operator()(R&& r, const T& value, Proj proj = {}) const { return (*this)(ranges::begin(r), ranges::end(r), value, proj); } }; inline constexpr __contains_fn contains {}; |
DNKpp (talk) 13:21, 8 April 2025 (PDT)
[edit] Typo in the Effects table of the span constructor page
In page https://en.cppreference.com/w/cpp/container/span/span
... in the table "Effects", at line (9) and (10), there is a typo on the two columns:
- in "data() after construction", this should be source.data() (resp. other.data())
- in "size() after construction", this should be source.size() (resp. other.size())
In other words, for these two lines, the columns are inverted.
Paercebal (talk) 03:03, 9 April 2025 (PDT)
[edit] Add tiny::optional to list of open-source C++ libraries
I suggest to add the tiny::optional library (https://github.com/Sedeniono/tiny-optional) to the list of open-source C++ libraries (https://en.cppreference.com/w/cpp/links/libs). Note: I am the author of that library.
It should be placed under the "Containers" section with the Description "Replacement for std::optional that does not waste memory unnecessarily." The license is BSL-1.0. The configuration is "header-only; cmake".
Sedenion (talk) 11:09, 14 April 2025 (PDT)
- Added. Many thanks for providing the metadata up-front
:)
✔ Done --Ybab321 (talk) 13:08, 14 April 2025 (PDT)
[edit] Typos in concat_view::iterator template parameters
On https://en.cppreference.com/w/cpp/ranges/concat_view/iterator the two helper concepts have Rs as a template parameter. The detailed descriptions reference Fs instead. Mpt (talk) 06:10, 15 April 2025 (PDT)
-
Fs
are defined as “the pack that consists of all elements ofRs
except the last element” right before the code blocks.✘ No change --Xmcgcg (talk) 09:19, 15 April 2025 (PDT)
[edit] The prev helper function in concat_view::iterator is incorrect
In https://en.cppreference.com/w/cpp/ranges/concat_view/iterator/helpers#prev the prev helper function has an error in the 'otherwise' case. `else --get-iter<0>();` should be `else --get-iter<N>();` Mpt (talk) 06:49, 15 April 2025 (PDT)
[edit] minor fix?
In https://en.cppreference.com/w/cpp/language/aggregate_initialization
I believe the line in the appertainment analysis
// 3. 0 cannot appertain to x[0], therefore x[0] is replaced by x[0].s and x[0].t,
should be
// 3. 1 cannot appertain to x[0], therefore x[0] is replaced by x[0].s and x[0].t,
There is no '0' in the initializer clause, and 3 continues discussion of the appertainment of '1'.
Please let me know if this seems reasonable, or if (more likely) I have misunderstood.
Ing3 (talk) 08:58, 15 April 2025 (PDT) David
- Example updated.✔ Done --Xmcgcg (talk) 09:19, 15 April 2025 (PDT)
- Great that you also changed to the long (L) literals to distinguish from array indices and process steps! Thanks. Ing3
[edit] XCode 16.3 adds support for deducing this
https://developer.apple.com/documentation/xcode-release-notes/xcode-16_3-release-notes
178.26.2.49 10:35, 15 April 2025 (PDT)Curve
[edit] C11 Static assertion typo
Hi, in the heading of this page:
It seems like there's a typo:
_Static_assert ( expression ) (since C23)(deprecated in C23)
I guess this line should be replace from:
{{sdsc|notes={{mark since c23}}{{mark deprecated c23}}|{{ttb|_Static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|)}}}}
To:
{{sdsc|notes={{mark since c11}}{{mark deprecated c23}}|{{ttb|_Static_assert}} {{ttb|(}} {{spar|expression}} {{ttb|)}}}}
I hope everything was clear.
Warebrew (talk) 00:03, 16 April 2025 (PDT) Warebrew
- No, it's correct as is. In C11 the user is forced to provide a message alongside the condition, as shown in (1). (3) and (4) are both C23 additions. 2A02:587:7E0D:3800:451D:1325:FFC4:DD60 00:32, 16 April 2025 (PDT)
[edit] std::ranges::lower_bound, missing comma
https://en.cppreference.com/w/cpp/algorithm/ranges/lower_bound on (2) (since c++26):
... class T = std::projected_value_t<ranges::iterator_t<R>, Proj> [!COMMA!]
std::indirect_strict_weak_order ...
2407:7000:B040:3700:E8E7:38EC:E936:64D3 22:14, 16 April 2025 (PDT) Simon Hill
[edit] The "schoolboy error" note on lock guards
So there is this "schoolboy error" note added to std::scoped_lock and later copied to std::lock_guard which now reads:
A common beginner error is to "forget" to give aLOCK_GUARD
variable a name, e.g. std::LOCK_GUARD(mtx); (which default constructs aLOCK_GUARD
variable namedmtx
) or std::LOCK_GUARD{mtx}; (which constructs a prvalue object that is immediately destroyed), thereby not actually constructing a lock that holds a mutex for the rest of the scope.
There are some problems:
- This should also be added to std::unique_lock, which suffers from this issue.
- std::lock_guard does not have a default constructor, so the former std::lock_guard(mtx); would not compile. It might make sense to remove that part, or clarify that it does not apply to
std::lock_guard
itself.
Based on the two points above, you can also maintain a single source of truth in one of the pages and link to it in the other two. It depends on the convention of this wiki.
Reference: CppCon 2017 talk https://youtu.be/lkgszkPnV8g?t=2276
--Stevenlele (talk) 00:59, 19 April 2025 (PDT)
- Whoops, my bad on the lock guard page, always appreciate people spotting my blunders. Fixed and added unique lock note as requested, thanks. ✔ Done --Ybab321 (talk) 03:52, 21 April 2025 (PDT)
[edit] ranges::contains implementation status
std::ranges::contains is implemented in LLVM 18, not 19
https://github.com/llvm/llvm-project/commit/fdd089b500631b123bc70d04dd016b41f9323f4c shows that llvmorg-18.1.0 tag contains this commit
Ranges status page in LLVM 18 changelog (https://releases.llvm.org/1.1.0/projects/libcxx/docs/Status/Ranges.html#algorithms) appears to be incorrect. 178.67.159.115 18:45, 19 April 2025 (PDT)
[edit] emplace_back documentation fix
The Parameters > Type requirements section of Template:cpp/container/emplace_back is missing a "not" from the sentence "T is MoveInsertable into <container>." Jhopkins (talk) 01:28, 21 April 2025 (PDT)
[edit] K&R functions UB
I suggest replacing "will invoke undefined behavior if the number of arguments doesn't match the number of parameters." in https://en.cppreference.com/w/c/language/function_declaration with something that also includes that UB will occur on type mismatch, as demonstrated in the example following that line. Anselm Schüler (talk) 13:56, 21 April 2025 (PDT)
[edit] std::vector clarification of std::vector<bool> specialization
I believe this sentence in the opening sentence of the std::vector article is incorrect in general as written, and should be amended with the parenthetical I added: “The elements are stored contiguously, which means *(for T other than bool)* that elements can be accessed not only through iterators, but also using offsets to regular pointers to elements.” Crutch (talk) 05:38, 23 April 2025 (PDT)
[edit] 似乎有符号错误
At https://en.cppreference.com/w/cpp/string/basic_string/deduction_guides, in the third and fourth deduction guides, there seems to be an extra > in the template declaration.
template< class CharT, class Traits, class Alloc = std::allocator<CharT>> > // Extra '>' here? basic_string( const CharT*, typename /* see below */::size_type, const Alloc& = Alloc() ) -> basic_string<CharT, Traits, Alloc>;
- Deduction guide (3) fixed.✔ Done No change needed for deduction guide (4). --Xmcgcg (talk) 05:52, 25 April 2025 (PDT)
[edit] Typo in the Notes section
Current: The standard library specializes mathematical constant variable templates for all floating-point types (i.e. float, doublelong double , and fixed width floating-point types(since C++23)).
Missed comma + space: float, double, long double Also unnecessary space before comma after the last `double`
[edit] Improve example for reverse_iterator.base
Issues with the example on https://en.cppreference.com/w/cpp/iterator/reverse_iterator/base:
- The vector is `{0, 1, 2, 3, 4, 5}`
- `it` is `begin() + 3`, so, `*it == 3`, but also, `*begin() + 3 == 3` by due to values in vector
- `r_it(it)` is set so we have `*r_it == 2`, but also, `rend() + 3 == 2`
- `*(r_it.base()-1) == 2` but also `*(r_it.base())-1 == 2`
Let's make the vector `{1, 2, 4, 8, 16, 32}` and these coincidences go away
- The example is OK. The elements of the vector are used as shortcuts to represent the actual positions of the iterators relative to
begin()
.✘ No change --Xmcgcg (talk) 05:52, 25 April 2025 (PDT)
[edit]
In https://en.cppreference.com/mwiki/index.php?title=cpp/thread/shared_mutex
There is currently:
If one thread has acquired the shared lock (through lock_shared, try_lock_shared), no other thread can acquire the exclusive lock, but can acquire the shared lock.
The last verb of the sentence would have "no other thread" as its subject, which is not the intended meaning AFAIK.
Would update to something along the lines of:
If one thread has acquired the shared lock (through lock_shared, try_lock_shared), no other thread can acquire the exclusive lock, but they can acquire the shared lock.
If one thread has acquired the shared lock (through lock_shared, try_lock_shared), no other thread can acquire the exclusive lock, but threads can acquire the shared lock.
With a preference for the former if the shared_lock is not reentrant, and a preference for the later if it is.
I believe the sane implementation of a shared lock is probably reentrant, so would go with
If one thread has acquired the shared lock (through lock_shared, try_lock_shared), no other thread can acquire the exclusive lock, but threads can acquire the shared lock.
Thank you,
199.19.253.84 06:24, 25 April 2025 (PDT) Alceste_
[edit] Highlight possible exception in std::chrono::zoned_time<Duration,TimeZonePtr>::operator=
std::chrono::zoned_time::operator= uses zone->to_sys(other) which can throw; this should be stated on the reference page. 204.75.143.6 09:03, 25 April 2025 (PDT)
[edit]
In {{c/preprocessor/navbar content}}, please change
{{nv ln | cpp/preprocessor/impl | #pragma | _Pragma | notes=<br>{{mark c99}}}}
to
{{nv ln | c/preprocessor/impl | #pragma | _Pragma | notes=<br>{{mark c99}}}}
to link to the C material instead of the C++ material.
--SamuelBronson (talk) 18:38, 26 April 2025 (PDT)
- ✔ Fixed --Space Mission (talk) 19:06, 26 April 2025 (PDT)
[edit] void* memmove( void* dest, const void* src, size_t count );
void* memmove(void* dest, const void* src, size_t count);
In case source and destination regions do overlap, the source region gets changed after the call (indirectly). So const qualifier should be removed, shouldn't it? Avcpp (talk) 09:32, 28 April 2025 (PDT)
[edit] Example of std::unreachable_sentinel has undefined behaviour
Maybe we should at least note about this.
- Example replaced.✔ Done Let's avoid passing invalid ranges directly to standard library algorithms. --Xmcgcg (talk) 11:29, 29 April 2025 (PDT)
[edit] wrong template arguments in expected constructor
Hi, according to https://eel.is/c++draft/expected#void.general the in_place constructor takes no template arguments. i.e. overload (20) in https://en.cppreference.com/w/cpp/utility/expected/expected reads
template <class... Args> constexpr explicit expected(in_place_t) noexcept;
it should be
constexpr explicit expected(in_place_t) noexcept;
Thank you, Maikel
141.113.3.31 04:20, 30 April 2025 (PDT)
- ✔ Fixed, danke: overload (20). --Space Mission (talk) 06:33, 30 April 2025 (PDT)
Dear maintainer,
I have noticed that the API for C++17 filesystem 'uintmax_t remove_all(const path& p, error_code& ec);' lacks 'noexcept'.
Cyyever (talk) 01:53, 1 May 2025 (PDT)
- That is correct https://eel.is/c++draft/fs.op.remove.all --Ybab321 (talk) 06:30, 1 May 2025 (PDT)
[edit] Static Initialization Order Fiasco
The whole page is misleading becuase the author does not appear to be aware of the C++ standard document N5008 section 6.9.3.2. clause 3. There it says "an implementation is permitted" which makes for uncertainty about the initialisation of later statics within a unit and therefore uncertainty in oredered initialisation within a unit. Much older standard documents also have this.
- cpp/language/siof could use less alarmist language and more examples and solutions, but it describes the topic as it is generally understood (just added a link to the isocpp superfaq for the official-ish definition). Dynamic to static promotion (basic.start.static/3, reflected on cppreference in cpp/language/initialization#Early_dynamic_initialization) isn't part of it, and in fact is considered to be a solution when enforced by `constinit`. --Cubbi (talk) 14:37, 4 May 2025 (PDT)
[edit] Update description for the Mutexgear library
Hi,
Could you, please, update description for the Concurrency/Mutexgear library to include a new object name, like this?
! MutexGear | A mutex-only synchronization (wheel, rwlock, maintlock, work queues) C/C++11 library | The MutexGear Library | configure, msvc, make |-
Thank you. Oleh derevenko (talk) 23:40, 1 May 2025 (PDT)
- Sure, ✔ Done: updated.) --Space Mission (talk) 09:12, 2 May 2025 (PDT)
[edit] Incorrect numbering of Move and Copy constructor
select standard revision as C++20
number 7 shows up as `vector( vector&& other ); (7)` which is the move constructor but the text says "7) The copy constructor. "
Similar numbering issues follow
- ✔ Fixed, e.g., here:
- --Space Mission (talk) 07:46, 7 May 2025 (PDT)
[edit] Multiple issues in description of getline() parameter size_t *n
There are several issues regarding the parameter size_t *n on page c/experimental/dynamic/getline.
- There appears to be no mention that if the buffer at *lineptr is allocated or reallocated, the final length of the buffer is written to *n. This behavior is defined in both POSIX and Draft WG14/N1388 of ISO/IEC TR 24731-2:2010. (The actual published ISO document is behind a paywall.)
- The description for function (3) contains the following sentence:
This is easy to misinterpret as "...the (type*lineptr
may be null, in which case*n
is ignored andgetline
allocates a new buffer as if by malloc.size_t *
) addressn
is ignored..." instead of "...the (typesize_t
) value pointed to byn
is ignored...", implying that NULL (or arbitrary garbage) may be passed to n if *lineptr is also NULL. Due to the fact that *n is written to, this is not the case and n must always be passed an address allocated for size_t, or behavior is undefined. The revised sentence might read:
(Perhaps with an added footnote clarifying further that passing an address not allocated for size_t always results in undefined behavior.)*lineptr
may be null, in which case the initial value of*n
is ignored andgetline
allocates a new buffer as if by malloc.
- The statement below is incorrect:
If
Behavior is undefined if*lineptr
is not null, the behavior is undefined if*lineptr
is not a pointer that can be passed to free or if*n
is less than the size of the allocated memory pointed to by*lineptr
.*n
is greater than the size of the memory pointed to by*lineptr
.
NextDoorTech (talk) 19:53, 5 May 2025 (PDT)
- ✔ Done cross-checked with posix and applied these, hopefully --Cubbi (talk) 11:30, 12 May 2025 (PDT)
[edit] localtime( &t ) can be thread-safe
On the page https://en.cppreference.com/w/c/chrono/localtime, you write "The function localtime may not be thread-safe."
But it is not right for Microsoft CRT, see https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/localtime-localtime32-localtime64?view=msvc-170
> Both the 32-bit and 64-bit versions of gmtime, mktime, mkgmtime, and localtime all use a single tm structure per thread for the conversion. Each call to one of these routines destroys the result of the previous call.
And it can be verified experimentally by checking that localtime function in Microsoft CRT (unlike GNU) returns distinct pointers from different threads: https://gcc.godbolt.org/z/fWcxGYahe
Fchel (talk) 02:17, 6 May 2025 (PDT)
[edit] Incorrect complexity of std::flat_set::insert
I see that complexity of std::flat_set::insert is specified as linear which is not true
https://en.cppreference.com/w/cpp/container/flat_set/insert
[edit] Complexity
size()
.size()
.
I also see, that, for example, first overload of insert is "Equivalent to return emplace(value);.", but complexity of emplace has written correctly: "Logarithmic in the size of the container."
The same in gcc-15 implementation
https://gcc.gnu.org/onlinedocs/gcc-15.1.0/libstdc++/api/a00098_source.html#l00399
- All the single value insertions are are linear time by the standard [28]. I think this is actually more constraining than the currently stated time complexities (which are stated "plus the cost of insertion"), because they preclude the possibility of the underlying container having super-linear insertion time. In general, I'm not sure if we want to provide time complexities that are more precise than the standard --Ybab321 (talk) 01:51, 14 May 2025 (PDT)
[edit] Page "strcpy()/strncopy()" have unclear statement
In https://en.cppreference.com/w/c/string/byte/strcpy and https://en.cppreference.com/w/c/string/byte/strncpy, the paragraph "The behavior is undefined if the size of the character array pointed to by dest <= strnlen_s(src, destsz) < destsz; in other words, an erroneous value of destsz does not expose the impending buffer overflow." is unclear. Rather, the "in other words" elaborator doesn't make sense to me. What does "expose" mean? Does it mean that an error should be raised, or that writing data into an unallocated/allocated for another purpose memory location may occur?
If the later, I think replacing it with "in other words, an erroneous value of destsz can still result in a buffer overflow"
[edit] Page "strcpy()/strncopy()" have unclear statement
In https://en.cppreference.com/w/c/string/byte/strcpy and https://en.cppreference.com/w/c/string/byte/strncpy, the paragraph "The behavior is undefined if the size of the character array pointed to by dest <= strnlen_s(src, destsz) < destsz; in other words, an erroneous value of destsz does not expose the impending buffer overflow." is unclear. Rather, the "in other words" elaborator doesn't make sense to me. What does "expose" mean? Does it mean that an error should be raised, or that writing data into an unallocated/allocated for another purpose memory location may occur?
If the later, I think replacing it with "in other words, an erroneous value of destsz can still result in a buffer overflow" Calumapplepie (talk) 23:15, 9 May 2025 (PDT)
[edit] Typo in "constexpr specifier (since C23)"
This text has a typo:
> It still has linkage appropriate to its declaration and it exist at runtime to have its address taken;
✔ Fixed.) --Space Mission (talk) 00:36, 12 May 2025 (PDT)
[edit] Grammar fix
For grammar, the line saying "...POSIX-based implementations of aligned_alloc inherit this requirements" should read "...POSIX-based implementations of aligned_alloc inherit these requirements."
- Fixed.✔ Done There is only one requirement, so the singular form is used here. --Xmcgcg (talk) 06:51, 12 May 2025 (PDT)
[edit] Double negatives do not contribute to readability.
I would suggest that the sentence "without the elements that fail to satisfy a predicate" be changed to "with only the elements that satisfy a predicate" to improve readability.
- On which page? --Ybab321 (talk) 08:57, 13 May 2025 (PDT)
- ✔ Updated, here: cpp/ranges/filter_view, at @1@. :) --Space Mission (talk) 15:05, 17 May 2025 (PDT)
[edit] [ c/error ] description infocard for static_assert is misleading
The header description infocard for the macro keyword static_assert on c/error is a bit misleading - the (removed in C23) note seems to imply that the feature no longer exists at first glance. The only mention that static_assert is a C23 core keyword instead of a macro defined in <assert.h> is in an unlinked footnote at the bottom of the page.
IMO, the existing card for the now-removed macro keyword should be left alone, but an additional card for the new non-macro keyword should be added to indicate the functionality has not been removed - just significantly changed from a semantic (but not functional) standpoint. I noticed that there's not a {{dsc keyword}} template, so creating one may be a good idea. I assume there are similar problems on pages with cards for the handful of other macro-turned-C23-keywords.
NextDoorTech (talk) 19:47, 13 May 2025 (PDT)
- There's a note about it being a keyword as of C23 in the notes section of the page in question, the library static_assert page also has this note. The macro has been removed from the standard library, so we can't not say it's removed in the library documentation. Would be nice I guess to remove that initial double-take about the feature more generally being removed, but I think it's sufficiently elaborated on as is. --Ybab321 (talk) 00:55, 14 May 2025 (PDT)
[edit] The example failed to run with the line `std::destroy_at(ptr);`
Is this a GCC bug? or i misunderstood the lifetime of `uninitialized` variable?
- On which page? --Ybab321 (talk) 02:48, 15 May 2025 (PDT)
- They all are here and they run fine.) --Space Mission (talk) 06:49, 19 May 2025 (PDT)
[edit] basic_ostream::sentry's constructor is not guaranteed to set failbit when eofbit and/or badbit are set
According to the page on FormattedOutputFunction : "if eofbit or badbit are set on the output stream, sets the failbit as well, and if exceptions on failbit are enabled in this output stream's exception mask ((exceptions() & failbit) != 0), throws ios_base::failure."
This is not required in the standard and at least libc++ does not do it.
[edit] Suggestion to correct the time complexity description for std::unordered_set::clear()
The current documentation states that the time complexity of std::unordered_set::clear() is “Linear in the size of the container (i.e., the number of elements).” However, in practice, this operation is more accurately described as “Linear in the bucket count” rather than the number of elements. Implementations typically iterate over each bucket to remove element references, which leads to complexity that depends primarily on the bucket count.
gcc: https://github.com/gcc-mirror/gcc/blob/fd50d2a24adaff9a9ba749fd0a1eb5a5c5ee35a8/libstdc%2B%2B-v3/include/bits/hashtable.h#L2707-L2720 clang LLVM: https://github.com/llvm/llvm-project/blob/ad060dfa4c910e8253ba328be947ef70f6597326/libcxx/include/__hash_table#L1338-L1348
Therefore, I suggest revising the documentation from:
“Complexity: Linear in the size of the container.”
to:
“Complexity: Linear in the bucket count.”
This change would more accurately reflect the actual behavior of most standard library implementations.
Additionally, the same reasoning applies to std::unordered_map::clear().
- Both _M_deallocate_nodes (used by libstdc++) and __deallocate_node (used by libc++) iterate over all the nodes owned by the container. In order to erase an element, you have to call the
destroy()
static member function of an Allocator (required by Erasable). Callingdestroy()
size() times is needed to erase all elements, and that is the real part that primarily contributes to the complexity. ✘ No change --Xmcgcg (talk) 09:18, 18 May 2025 (PDT)- There's no value in looking at implementations in this case. Each element has to be destroyed, so it's at least linear in the size of the container; the number of buckets has no bearing on the time complexity, because time complexity is expressed in terms of operations on contained objects --Ybab321 (talk) 11:55, 18 May 2025 (PDT)
[edit] Member initializer list syntax for parameter packs is misleading
In https://en.cppreference.com/w/cpp/language/constructor, syntax (3) for member initializers is given as parameter-pack ...
, where parameter-pack refers to a "name of a variadic template parameter pack". To me, this suggests a use like
template<class... Mixins> class X : public Mixins... { public: X(const Mixins&... mixins) : Mixins... {} };
, which in my understanding is invalid.
Maybe something like
class-or-identifier ( expression-list (optional) )
|
(1) | ||||||||
class-or-identifier braced-init-list | (2) | (since C++11) | |||||||
parameter-pack ( expression-list (optional) ) ...
|
(3) | (since C++11) | |||||||
parameter-pack braced-init-list ...
|
(4) | (since C++11) | |||||||
could be a more helpful formulation?
Robot-controller (talk) 07:40, 18 May 2025 (PDT)
[edit] Defect report LWG149 is applied to the wrong version
In Template:cpp/container/insert, the defect report LWG149 is specified as applied to C++98.
But the report only mentions C++11, and is also specified in the C++11 category of the lwg-status
document.
Also, libstdc++
still return void for versions prior to C++11: source code
Prototypes "until C++11" returning void should also be added to the list of prototypes.
Simon Cros (talk) 04:10, 21 May 2025 (PDT)
- The official definition of the “C++11” status is “The full WG21/PL22.16 committee has voted to accept the Defect Report's Proposed Resolution into the published 2011 revision to the C++ standard, ISO/IEC IS 14882:2011(E).” (see C++ Standard Library Active Issues List) Only defects in C++98 can have this status. The version in the “Applied to” column is the earliest defective and fixable version.
- libstdc++ simply did not backport many C++98-era DRs to C++98 mode, like vector::shrink_to_fit(). --Xmcgcg (talk) 10:04, 21 May 2025 (PDT)