我了解到评估未初始化的变量是未定义的行为。特别int i = i;
是未定义的行为。我已阅读未初始化变量用作其自身初始化程序的行为是什么?
但是,使用引用变量来初始化自身也是未定义的行为吗?特别是,int &ref = ref;
根据 C++ 标准,UB 也是吗?
int &ref = ref; // Is this well-formed or ill-formed or UB
Run Code Online (Sandbox Code Playgroud)
所有编译器都会编译上述程序(clang 会发出警告)。这是因为它是未定义的行为,所以任何事情都可以发生,还是程序格式良好?
此外,如果我为 分配一些值ref
,程序的行为会与之前的情况相比发生变化吗?
int &ref = ref;
int main()
{
ref = 1; //does this change the behavior of the program from previous case
}
Run Code Online (Sandbox Code Playgroud)
我注意到对于第二个片段,我们遇到了段错误。
我读过的一些参考文献是:
我有一个友元函数模板operator<<
,它可以与 gcc 和 clang 一起使用,但不能与 msvc 一起使用。
#include <iostream>
#include <type_traits>
template< typename T, std::enable_if_t< T{1}, int> =0 >
class Foo
{
template< typename Ar, typename R>
friend Ar& operator<<(Ar& os, const Foo<R>& foo)
{
return os;
}
};
int main()
{
Foo<int> i;
std::cout << i; //works with gcc and clang but does not compile with msvc
}
Run Code Online (Sandbox Code Playgroud)
我想知道哪个编译器根据 C++ 标准具有正确的行为。msvc 错误说:
<source>(4): error C2972: 'Foo': template parameter 'unnamed-parameter': the type of non-type argument is invalid …
Run Code Online (Sandbox Code Playgroud) 我最近了解到,一个类中可以有多个默认构造函数。然后我编写了以下程序,使用 msvc 进行编译,但是 clang 和 gcc 都无法编译它。
\nstruct A\n{\n\xc2\xa0 explicit A(int = 10);\n\xc2\xa0 A()= default;\n};\n\nA a = {}; //msvc ok but gcc and clang fails here\n
Run Code Online (Sandbox Code Playgroud)\n\n我想知道根据 C++17 标准哪个编译器是正确的。
\n海湾合作委员会 说:
\n<source>:8:8: error: conversion from \'<brace-enclosed initializer list>\' to \'A\' is ambiguous\n 8 | A a = {}; //msvc ok but gcc and clang fails here\n | ^\n<source>:5:3: note: candidate: \'constexpr A::A()\'\n 5 | A()= default;\n | ^\n<source>:4:12: note: candidate: \'A::A(int)\'\n 4 | explicit …
Run Code Online (Sandbox Code Playgroud) 我正在学习用户定义的文字,我编写了以下与 gcc 和 msvc 一起使用的程序,但 clang 拒绝它。现场演示
#include <array>
template<std::size_t N>
struct Literal
{
std::array<char, N> arr;
constexpr Literal(char const(&pp)[N]): arr(""){}
};
template<Literal>
constexpr auto operator""_S()
{
return 4;
}
int main() {
auto i = "test"_S;
auto j = "ch"_S;
}
Run Code Online (Sandbox Code Playgroud)
我想知道哪个编译器在这里是正确的。clang 上的错误说:
<source>:7:48: error: initializer-string for char array is too long, array size is 3 but initializer has size 5 (including the null terminating character)
7 | constexpr Literal(char const(&pp)[N]): arr(""){}
|
<source>:17:15: note: in instantiation of …
Run Code Online (Sandbox Code Playgroud) 我编写了以下使用new
. 但问题是 clang 拒绝该程序,而 gcc 和 msvc 接受它。我的问题是哪个编译器就在这里?
struct C{
C(int);
};
int main() {
C *ptr{new C[]{1}}; //clang rejects but gcc accepts
}
Run Code Online (Sandbox Code Playgroud)
铿锵 说:
<source>:6:21: error: no matching constructor for initialization of 'C'
6 | C *ptr{new C[]{1}}; //clang rejects but gcc accepts
| ^
<source>:3:4: note: candidate constructor not viable: requires 1 argument, but 0 were provided
3 | C(int);
| ^ ~~~
<source>:2:8: note: candidate constructor (the implicit copy constructor) not viable: requires …
Run Code Online (Sandbox Code Playgroud) 我了解了 SFINAE 原理及其各种用途。然后我编写了以下程序,该程序使用 gcc 编译,但不使用 msvc 和 clang 编译。现场演示。
#include <iostream>
#include <type_traits>
template <typename T> class Container {
public:
template<typename U = T>
std::enable_if_t<std::is_same_v<T, int>> foo(const T&)
{
}
};
template<typename T>
void func(T&& callable)
{
Container<int> c;
(c.*callable)(4);
}
int main(){
//works with gcc but not with clang and msvc
func(&Container<int>::foo);
}
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,上面的程序适用于 gcc,但不适用于 clang 和 msvc,而且我不知道这里是哪个编译器。这个程序是格式良好还是格式错误等。
我已经了解了constexpr
C++ 中的变量,并阅读了int i =0; constexpr int j = i;
失败的内容,因为i
它不是有意义的常量表达式。但是当我对类的变量做同样的事情时,它起作用了。
struct C{};
int main()
{
int i = 0; //i is not a constant expression as expected
//constexpr int j = i; //this fails AS EXPECTED
C c;
constexpr C d = c; //WHY DOESN'T THIS FAIL??
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,constexpr C d = c;
编译没有任何问题,不像constexpr int j = i;
即使c
也不是常量表达式。
我想知道这背后的原因。
我了解了 C++ 中的继承。然后为了检查我是否正确理解了这个概念,我编写了下面给出的程序,该程序被 clang 拒绝,但被 gcc 和 msvc 接受。现场演示
#include <array>
#include <iostream>
class Base
{
private:
int data;
public:
Base(int pdata):data(pdata) {}
Base(const Base&){std::cout <<" Copy base";}
};
class Derived : public Base
{
};
int main()
{
Derived d(1); //rejected by clang but accepted by gcc and msvc
}
Run Code Online (Sandbox Code Playgroud)
我正在使用 C++20,想知道C++20 中哪个编译器是正确的。我还注意到,对于 C++17,所有编译器都拒绝这一点,但从 c++20 开始,gcc 和 msvc 开始编译程序。看来 c++20 标准发生了一些变化。但我不知道这个变化是什么(假设有任何这样的变化)以及程序在 c++20 中是否格式良好。
clang c++20 错误说:
<source>:19:12: error: no matching conversion for functional-style cast from 'int' …
Run Code Online (Sandbox Code Playgroud) 我编写了以下程序,该程序使用 msvc 编译,但不使用 gcc 和 clang 编译。演示
template<int x>
struct X {
consteval static int get();
int f() const;
};
//compiles with msvc but not with gcc and clang
template<int x> int X<x>::get(){ return x; }
int main() {
constexpr int i = X<4>::get();
}
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,MSVC 编译了上面的演示,而 GCC 和 Clang 拒绝了它。海湾合作委员会 说:
template<int x>
struct X {
consteval static int get();
int f() const;
};
//compiles with msvc but not with gcc and clang
template<int x> int X<x>::get(){ return …
Run Code Online (Sandbox Code Playgroud) 我正在使用 Stanley 的《C++ Primer》一书学习 C++。特别是,关于“指针转换”的部分说:
指向任何非常量类型的指针都可以转换为
void*
读完本文后,我编写了以下程序,该程序使用 msvc 进行编译,没有任何诊断,但被 gcc 和 clang 拒绝。演示
int func()
{
return 4;
}
int main()
{
void* ptr = &func; //works with msvc but rejected by clang and gcc
}
Run Code Online (Sandbox Code Playgroud)
正如你所看到的,上面的程序适用于 msvc,但 gcc 说error: invalid conversion from 'int (*)()' to 'void*'
。
我想知道哪个编译器在这里是正确的。请注意,我已将/permissive-
flag 与 msvc 一起使用以使其符合标准。
c++ pointers function-pointers language-lawyer pointer-conversion
我编写了以下程序,该程序使用 msvc 编译,但不使用 gcc 和 clang 编译。 演示
int main() {
constexpr auto func = []()constexpr { return 1; };
auto i = []{return func();};
}
Run Code Online (Sandbox Code Playgroud)
我想知道这里的编译器是哪个?
海湾合作委员会 说:
<source>: In lambda function:
<source>:3:28: error: 'func' is not captured
3 | auto i = []{return func();};
| ~~~~^~
<source>:3:15: note: the lambda has no capture-default
3 | auto i = []{return func();};
| ^
<source>:2:20: note: 'constexpr const main()::<lambda()> func' declared here
2 | constexpr auto func = []()constexpr { …
Run Code Online (Sandbox Code Playgroud) 我最近学习了指向成员语法的指针,然后编写了如下所示的程序,msvc 可以编译,但 gcc 和 clang 拒绝。
#include <iostream>
#include <type_traits>
#include <concepts>
struct C
{
int foo()
{
return 5;
}
};
int main()
{
int (C::*ptr)() = &(C::foo); //msvc compiles but not gcc and clang
}
Run Code Online (Sandbox Code Playgroud)
我想知道哪一个是正确的。现场演示
我通过 Stanley 的《C++ Primer》一书了解了 C++ 中的类模板。然后我编写了以下程序,令人惊讶的是,它可以使用 gcc 编译,但不能使用 clang 编译。我不知道为什么会这样。也就是说,C++20 中哪个编译器是正确的。我还阅读了有关未定义行为的信息,但我不确定该程序是否具有该行为。
template <typename T>
struct test
{
T y;
};
int main()
{
test t{1}; //compiles with gcc and msvc but not with clang!
}
Run Code Online (Sandbox Code Playgroud)
那么有人可以告诉我根据 C++20 标准什么是正确的行为吗?
c++ ×13
language-lawyer ×11
c++20 ×4
templates ×3
compiler-bug ×2
aggregate ×1
c++17 ×1
pointers ×1
reference ×1
visual-c++ ×1