标签: clang++

模板函数中使用的类的前向声明不是由clang ++编译的

有这个代码:

class A;

template <class T>
void fun() {
   A a;
}

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

int main() { 
   fun<int>(); 
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

g ++ 4.5和g ++ 4.7编译时没有错误.但是clang ++ 3.2(trunk)给出了这个错误:

main.cpp:5:6: error: variable has incomplete type 'A'
   A a;
     ^
main.cpp:1:7: note: forward declaration of 'A'
class A;
      ^
Run Code Online (Sandbox Code Playgroud)

根据C++标准,哪个编译器是正确的?

c++ templates g++ forward-declaration clang++

12
推荐指数
2
解决办法
2080
查看次数

如何指示gcc/clang将临时文件输出到特定目录

使用--save-temps选项保存临时文件时,gcc/clang会将临时文件输出到与输入文件相同的目录中.是否有选项指示gcc将文件输出到其他目录.

要么

不使用--save-temps选项时,临时文件是在默认目录(即$ TMPDIR,如/ tmp)中创建的,但是一旦创建了目标文件,它们就会被删除.有没有办法指示编译器保留这些文件而不是删除它们(我认为唯一的选择是--save-temps,它有上述问题)

command-line gcc g++ clang clang++

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

为什么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
查看次数

无法在 ubuntu 上使用 clang++ 构建简单的 C++ 应用程序

我无法在仿生海狸上使用 clang-6.0 构建简单的 hello world 应用程序,构建命令失败并显示以下错误。

 clang++-6.0 -std=c++17 -stdlib=libc++ hello.cc -o hello 
/usr/bin/ld: cannot find -lc++abi
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)

这个 c++abi 库是什么,我在哪里可以找到它??请指教。

clang++

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

是否需要初始化参考变量主模板,即使它从未实例化过?

在没有初始化主要参考模板的情况下在C++ 14中声明参考模板是否合法,只要它从未实例化?

template<class T>
const T& ref;

template<>
auto ref<int> = 1;

auto x = ref<int>;
Run Code Online (Sandbox Code Playgroud)

这会在GCC和Clang上产生不同的结果:

$ g++ -std=c++14 -c ref.cpp
$

$ clang -std=c++14 -c ref.cpp
ref.cpp:2:10: error: declaration of reference variable 'ref' requires an
      initializer
const T& ref;
         ^~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)

没有必要初始化主要参考模板,因为在实例化之前,它是模板,而不是参考.

我发现我可以这样做:

template<class T>
const T& ref = "Meaningless initialization with any value of any type";

template<>
auto ref<int> = 1;

auto x = ref<int>;
Run Code Online (Sandbox Code Playgroud)

因为显然GCC和Clang都接受但忽略了参考模板初始化器RHS,只要它是一个有效的表达式并且主参考模板永远不会被实例化.任何类型的任何表达式都满足Clang的初始化要求.

只要主参考模板从未实例化,GCC就不需要初始化程序.这似乎是"在精神上"的正确行为,因为在实际实例化参考模板之前,它不应该需要初始化器.

标准在参考模板上不是100%明确.这是我在变量模板实例化上找不到的东西:

14.7.1

除非已显式实例化或显式专门化变量模板特化,否则在使用特化时隐式实例化变量模板特化.

...

实现不应隐式实例化......不需要实例化的变量模板.

14.7.2

除了内联函数,从其初始值或返回值(7.1.6.4)推导出的类型的声明const …

c++ templates language-lawyer clang++ variable-templates

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

为什么不同块中相同命名的外部局部变量在 C++ 中的编译器之间获得不同的链接?

当我只是检查哪些链接被授予外部局部变量时,
我发现编译器之间的一些不同行为

例如,如果我测试了下面的代码,
正如您在评论中看到的那样,变量vars 有不同的链接

// foo.cpp
int var = 10;                // external linkage

// main.cpp
#include <iostream>

static int var = 100;        // internal linkage

int main() {
    extern int var;          // internal linkage
    std::cout << var << std::endl;
    {
        extern int var;      // g++: external linkage , clang++: internal linkage
        std::cout << var << std::endl;
        {
            extern int var;  // g++: external linkage , clang++: internal linkage
            std::cout << var << std::endl;
        }
    }
}       
Run Code Online (Sandbox Code Playgroud)

结果是 …

c++ g++ extern linkage clang++

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

将 xvalue 转换为非常量左值引用时,为什么 gcc 和 clang 中的编译器错误不一致?

有人可以解释为什么两个编译器都在第二个示例中抛出错误而只有 gcc 在第一个示例中抛出错误吗?它是否与static_cast作为 xvalue的结果有关?

int& example1 = reinterpret_cast<int&>(static_cast<int&&>(10));
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) no errors

int& example2 = reinterpret_cast<int&>(10);
//(gcc 10.2) error: invalid cast of an rvalue expression of type 'int' to type 'int&'
//(clang 11.0.0) error: reinterpret_cast from rvalue to reference type 'int &'
Run Code Online (Sandbox Code Playgroud)

我也不确定,但我认为第一个例子是格式良好的,因为根据标准,xvalue 是 glvalue 的一种类型,对吧?并且标准的这个[expr.reinterpret.cast]/11部分说我应该能够将 T1 泛左值转换为“对 T2 的引用”类型,在这种情况下,T1 与 T2 的类型相同。

c++ gcc clang language-lawyer clang++

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