microsoft / microsoft/STL

<compare>: `std::_Literal_zero` has an impact on real code.

Open
#4,359 14 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

external
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

Describe the bug

Our type std::_Literal_zero has an impact on real code.

From the comment: https://github.com/microsoft/STL/pull/4332#issuecomment-1919524313

Command-line test case

#include <compare>

template<typename T, typename U>
constexpr bool not_equal(T lhs, U rhs) 
requires(requires(T lhs, U rhs) { lhs != rhs; })
{
        return lhs != rhs;
}

template<typename T, typename U>
constexpr bool not_equal(T lhs, U rhs) 
requires(!requires(T lhs, U rhs) { lhs != rhs; })
{
        return false;
}

int main() {
    constexpr int int_zero = 0;
    constexpr unsigned int unsigned_zero = 0;
    constexpr auto ordering = 1 <=> 1;
    //constexpr bool b = not_equal(ordering, unsigned_zero);
    constexpr bool b = not_equal(ordering, int_zero);
    return b == false;
}


C:\Temp>cl /EHsc /W4 /WX /std:c++latest .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.39.33321 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.

repro.cpp
.\repro.cpp(7): error C7595: 'std::_Literal_zero::_Literal_zero': call to immediate function is not a constant expression
.\repro.cpp(7): note: failure was caused by a read of a variable outside its lifetime
.\repro.cpp(7): note: see usage of 'rhs'
.\repro.cpp(7): note: the template instantiation context (the oldest one first) is
.\repro.cpp(22): note: see reference to function template instantiation 'bool not_equal<std::strong_ordering,int>(T,U)' being compiled
        with
        [
            T=std::strong_ordering,
            U=int
        ]

Expected behavior

Should compile

STL version

https://github.com/microsoft/STL/commit/202e3820d6390505855ce9a58a4bcee4f28feacd

Additional context

Other compiler libraries compile the code: https://godbolt.org/z/1vbYbq5b7

We added std::_Literal_zero because of this issue: https://github.com/microsoft/STL/pull/3581

Previously using _Literal_zero = decltype(nullptr); warned this code:

#include <compare>

auto b = 1 <=> 2 < 0;

int main() {}
clang-cl /std:c++20 -Wzero-as-null-pointer-constant main.cpp
main.cpp(3,20): warning: zero as null pointer constant [-Wzero-as-null-pointer-constant]
auto b = 1 <=> 2 < 0;
                   ^
                   nullptr
1 warning generated.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by compiling the supplied reproducer with the referenced STL commit and compare the behavior of the two not_equal overloads. Read the implementation introduced for std::_Literal_zero and the earlier change linked in the issue; done means the reproducer compiles while preserving the warning-related behavior described in the report.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.