标签: clang++

会员没有归零,一个clang ++ bug?

请考虑以下代码:

class A {
public:
    int i;
    A() {}
};

class B {
public:
    A a;
    int i;
};

int main() {
    B* p = new B {};
    std::cout << p->i << " " << p->a.i << "\n";
}
Run Code Online (Sandbox Code Playgroud)

在clang ++中用-std = c ++ 11编译,p->i结果为零,但p->a.i没有.只要它的类没有用户提供的构造函数,整个对象是否应该归零?

编辑:由于评论中有一些广泛的讨论,我认为最好从标准中添加一些摘录:

对值初始化类型的对象T意味着:

  • 如果T是具有用户提供的构造函数(12.1)的(可能是cv限定的)类类型(第9节),则调用T的默认构造函数(如果T没有可访问的默认构造函数,则初始化是错误的);
  • 如果T是没有用户提供的构造函数的(可能是cv限定的)非联合类类型,则该对象是零初始化的,如果T隐式声明的默认构造函数是非平凡的,则调用该构造函数.
  • 如果T是数组类型,则每个元素都是值初始化的;
  • 否则,该对象被零初始化.

零初始化T类型的对象或引用意味着:

  • 如果T是标量类型(3.9),则将对象设置为值0(零),作为整数常量表达式,转换为T;
  • 如果T是(可能是cv限定的)非联合类类型,则每个非静态数据成员和每个基类子对象都是零初始化的,并且填充初始化为零位;
  • if T …

c++ clang c++11 clang++

14
推荐指数
3
解决办法
553
查看次数

我相信clang错误地允许内联友人函数访问封闭范围内的数据.gcc和vs2013都拒绝此代码

friend函数f无权访问封闭类的私有成员A.

#include <iostream>

class A{
    const static int p = 1;
    class B {
        friend void f() {
            std::cout << p << '\n';
            std::cout << q << '\n';
        }
    };
public:
    const static int q = 2;
};
void f();

int main()
{
    f();
}
Run Code Online (Sandbox Code Playgroud)

至少,这是我认为N4140中的[class.nest]/4所说的(见下文).

§9.7/ 4

与成员函数一样,嵌套类中定义的友元函数(11.3)位于该类的词法范围内; 它遵循与名称绑定相同的规则作为该类的静态成员函数(9.4),但它对封闭类的成员没有特殊的访问权限.

实例

c++ friend clang clang++ c++14

14
推荐指数
1
解决办法
231
查看次数

函数模板重载clang ++

g ++ 4.8.1和clang ++ 3.4为下一个代码提供了不同的结果:

// simplified code from a Logger module
#include <iostream>

template<class T> void tf(const T*) {  // clang++ 
    std::cout << "void tf(const T*)\n"; 
}

template<class T> void tf(T) {  // g++
    std::cout << "void tf(T)\n"; 
}

int main(){ 
    typedef std::ios_base& (*ph)(std::ios_base&);
    ph p = std::hex;
    tf(p); // or just tf(std::hex)
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚哪个变体是正确的(C++ 03).

c++ templates clang++

13
推荐指数
2
解决办法
248
查看次数

clang bug?命名空间模板类的朋友

下面的代码不是在clang下编译但是在gcc和VS下编译:

template<typename T> class bar;

namespace NS
{
    template<typename T>
    class foo
    {
        foo() {}

        template<typename U> friend class bar;
    };
}

template<typename R>
class bar
{
public:
    bar()
    {
        NS::foo<int> f;
    }
};


int main(int, char **)
{
    bar<int> b;        
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

它失败了:

main.cpp:20:22: error: calling a private constructor of class 'NS::foo<int>'

        NS::foo<int> f;    
                     ^

main.cpp:8:9: note: implicitly declared private here

        foo() {}   
        ^
Run Code Online (Sandbox Code Playgroud)

bar应该有权访问foo私有构造函数但看起来却没有.如果我删除namespace NS,它编译.

代码看起来很好,但也许我误解了C++标准.哪个编译器正确?

c++ g++ language-lawyer clang++

13
推荐指数
2
解决办法
1180
查看次数

有关ODR使用的另一个铿锵/ gcc差异?

为什么这个代码用GCC(4.9和5+)编译,而不是用clang(3.5-3.9)编译?

void test(const int&) { }
int main() {
  const int x = 42;
  auto f = []{ test(x); };
}
Run Code Online (Sandbox Code Playgroud)

我有一些模糊的想法,认为这种差异与ODR(一种定义规则)的使用有关,但我不太了解这一点,以便弄清楚这里发生了什么.

c++ g++ one-definition-rule c++11 clang++

13
推荐指数
2
解决办法
647
查看次数

如何抑制 clang++ 中的警告?

我编译了以下c++程序:

 int main() {  2==3;  }
Run Code Online (Sandbox Code Playgroud)

和:

clang++-5.0 -std=c++17 -Wunused-comparison prog.cpp
Run Code Online (Sandbox Code Playgroud)

并收到警告:

warning: equality comparison result unused [-Wunused-comparison]
2==3;
~^~~
Run Code Online (Sandbox Code Playgroud)

...所以,这可能不是在 CLANG 中抑制警告的正确方法。

clang 手册中,这部分是“TODO”。

禁用警告的正确命令行标志是什么?

warnings clang++

13
推荐指数
1
解决办法
2万
查看次数

为什么clang拒绝variadic模板的朋友功能

我有以下示例代码,简化为必需的,编译与gcc 6.1,gcc 7.0 head和Visual Studio 2015/2017RC,但没有任何clang版本.

#include <iostream>
#include <tuple>

using namespace std;

namespace outer {
  namespace test {

    template <typename A, typename B, typename...C>
    auto bar_(A&&, B&&, C&&... c) {
      return std::make_tuple(c._p...);
    }

  }

  template <typename A, typename B, typename...C>
  auto bar(A a, B b, C&&... c) {
    return test::bar_(std::move(a), std::move(b), std::forward<C>(c)...);
  }

  template<typename T>
  class foo
  {
    template <typename A, typename B, typename...C>
    friend auto test::bar_(A&&, B&&, C&&... c);

    int _p;
  public:
    foo(int f) : _p(f) {}
  }; …
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates clang++ c++14

12
推荐指数
1
解决办法
301
查看次数

成员在不同名称空间中的别名声明专门化

我刚刚在clang和gcc之间遇到了一个奇怪的区别,我想编译看起来类似于以下内容的代码:

namespace n1 {
  template <class T1, class T2>
  struct MyTemplate {
    struct Inner {};
  };
}

using namespace n1;
namespace n2 {
  using MyClass = MyTemplate<int, int>;
}

namespace n1 {
  using n2::MyClass;
  template<> struct MyClass::Inner {
    int member;
  };

  MyClass::Inner inner{0};
}
Run Code Online (Sandbox Code Playgroud)

Clang愉快地编写了这个:

$ clang++ -std=c++11 -c -o alias_specialization.o alias_specialization.cc
Run Code Online (Sandbox Code Playgroud)

但是gcc会抛出以下错误:

$ g++ -std=c++11 -c -o alias_specialization.o alias_specialization.cc

alias_specialization:15:30: error: declaration of ‘struct n1::MyTemplate<int, int>::Inner’ in namespace ‘n1’ which does not enclose ‘using MyClass = struct n1::MyTemplate<int, int>’ …
Run Code Online (Sandbox Code Playgroud)

c++ gcc clang c++11 clang++

12
推荐指数
1
解决办法
577
查看次数

使用char**argv时如何避免指针运算

尝试打印第一个命令行参数时:

std::cout << argv[0] << std::endl;
Run Code Online (Sandbox Code Playgroud)

clang-tidy发出警告:

警告:[cppcoreguidelines-pro-bounds-pointer-arithmetic]中的'不使用指针运算'

argv没有使用指针算法的替代方法来使用值?是不是char**通过任何明智的方法访问必须使用指针算术?

我欣赏有一些专门的函数来处理命令行参数,但它们似乎太重了,不能简单地打印一个参数.

我正在编写c++,使用clang编译器和构建cmake.

c++ pointer-arithmetic command-line-arguments clang-static-analyzer clang++

12
推荐指数
1
解决办法
2000
查看次数

表达副作用的Clang警告

给出以下源代码:

#include <memory>
#include <typeinfo>

struct Base {
  virtual ~Base();
};

struct Derived : Base { };

int main() {
  std::unique_ptr<Base> ptr_foo = std::make_unique<Derived>();

  typeid(*ptr_foo).name();

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

并编译它:

clang++ -std=c++14 -Wall -Wextra -Werror -Wpedantic -g -o test test.cpp

环境设置:

linux x86_64
clang version 5.0.0
Run Code Online (Sandbox Code Playgroud)

由于警告(注释-Werror)它不编译:

error: expression with side effects will be evaluated
      despite being used as an operand to 'typeid'
      [-Werror,-Wpotentially-evaluated-expression]
  typeid(*ptr_foo).name();
Run Code Online (Sandbox Code Playgroud)

(请注意:海湾合作委员会并未声称存在这种潜在问题)


有没有办法获得有关a指向的类型的信息unique_ptr而不产生那种警告?

注意:我不是在谈论禁用-Wpotentially-evaluated-expression或避免-Werror.

c++ typeid clang++

12
推荐指数
1
解决办法
2120
查看次数