与libc ++一起使用clang时,为什么会出现以下链接器错误:
$ clang++ -stdlib=libc++ po.cxx -lpoppler
/tmp/po-QqlXGY.o: In function `main':
po.cxx:(.text+0x33): undefined reference to `Dict::lookup(char*, Object*, std::__1::set<int, std::__1::less<int>, std::__1::allocator<int> >*)'
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Run Code Online (Sandbox Code Playgroud)
哪里:
$ nm -D /usr/lib/x86_64-linux-gnu/libpoppler.so | grep lookup | c++filt| grep \ Dict::lookup\(
00000000000c1870 T Dict::lookup(char*, Object*, std::set<int, std::less<int>, std::allocator<int> >*)
Run Code Online (Sandbox Code Playgroud)
代码很简单:
#include <poppler/PDFDoc.h>
int main()
{
Dict *infoDict;
Object obj;
infoDict->lookup((char*)"key", &obj);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我试图用C++编写代码,就像tail -f在linux中一样.我发现了这个问题:
如何在C++中阅读不断增长的文本文件?并实现了相同的.我创建了一个temp.txt并开始做echo "temp" >> temp.txt.但是我的程序没有打印对文件所做的更新.我做错了什么?这是我正在使用的代码
#include <iostream>
#include <string>
#include <fstream>
#include <unistd.h>
int main()
{
std::ifstream ifs("temp.txt");
if (ifs.is_open())
{
std::string line;
while (true)
{
while (std::getline(ifs, line)) std::cout << line << "\n";
if (!ifs.eof()) break; // Ensure end of read was EOF.
ifs.clear();
sleep(3);
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
UPDATE
我在linux机器上尝试了相同的代码并且它工作正常,但它不适用于Mac.我gcc用来编译代码.
gcc -v 给
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)
Target: …Run Code Online (Sandbox Code Playgroud) 这是一个简短的例子,用clang重现这个"没有可行的转换"柠檬,但对编译器行为的g ++差异有效.
#include <iostream>
struct A {
int i;
};
#ifndef UNSCREW_CLANG
using cast_type = const A;
#else
using cast_type = A;
#endif
struct B {
operator cast_type () const {
return A{i};
}
int i;
};
int main () {
A a{0};
B b{1};
#ifndef CLANG_WORKAROUND
a = b;
#else
a = b.operator cast_type ();
#endif
std::cout << a.i << std::endl;
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
住在Godbolt的
g ++(4.9,5.2)默默地编译; 而clang ++(3.5,3.7)编译它
如果 …
下面声明norm的C++ vector类中的成员函数标记为const和(据我所知)不包含任何副作用.
template <unsigned int N>
struct vector {
double v[N];
double norm() const {
double ret = 0;
for (int i=0; i<N; ++i) {
ret += v[i]*v[i];
}
return ret;
}
};
double test(const vector<100>& x) {
return x.norm() + x.norm();
}
Run Code Online (Sandbox Code Playgroud)
如果我打电话norm多次上const的实例vector(见test上面的函数)与GCC编译器(5.4版本)和优化开启(即-O3),那么编译器内联norm,但仍计算的结果norm多次,即使结果不应该改变.为什么编译器不优化第二次调用norm而只计算一次这个结果?这个答案似乎表明,如果编译器确定该norm函数没有任何副作用,编译器应该执行此优化.为什么在这种情况下不会发生这种情况?
请注意,我正在使用Compiler Explorer确定编译器生成的内容,并且下面给出了gcc版本5.4的程序集输出.clang编译器给出了类似的结果.另请注意,如果我使用gcc的编译器属性手动标记norm为使用const函数__attribute__((const)),那么第二次调用会根据需要进行优化,但我的问题是为什么gcc(和clang)不会自动执行此操作,因为norm定义可用?
test(vector<100u>&): …Run Code Online (Sandbox Code Playgroud) 这与我今天早些时候提出的问题非常相似。但是,我在该问题中引用的示例是不正确的。错误地,我查看的是错误的源文件,而不是实际出现我所描述的错误的文件。无论如何,这是我的问题的一个示例:
struct base { };
struct child1 : base { };
struct child2 : base { };
child1 *c1;
child2 *c2;
// Goal: iterate over a few derived class pointers using a range-based for loop.
// initializer_lists are convenient for this, but we can't just use { c1, c2 }
// here because the compiler can't deduce what the type of the initializer_list
// should be. Therefore, we have to explicitly spell out that we want …Run Code Online (Sandbox Code Playgroud) 我想这是一个g ++ bug,但我要求确认.
以下代码:
#include <complex>
#include <iostream>
int main()
{
std::complex<double> ac[10] = 23.5;
for (int i = 0; i < 10; ++i)
std::cout << ac[i] << ", ";
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无法在clang ++ 3.5上编译
"错误:数组初始化程序必须是初始化程序列表")
但用g ++ 4.9.2编译,没有错误或警告.
g ++编译的可执行文件的输出是
(23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0), (23.5,0),
Run Code Online (Sandbox Code Playgroud)
所以这个数组初始化
std::complex<double> ac[10] = 23.5;
Run Code Online (Sandbox Code Playgroud)
使用等号右边的值作为数组的每个元素的初始化(并且,我认为,如果它是标准接受的特征,则可能是有用的)
如果我用std::complex<double>数组替换double数组
double ac[10] = 23.5;
Run Code Online (Sandbox Code Playgroud)
g ++给出了类似于clang ++的错误:
"错误:数组必须用括号括起的初始化程序初始化".
另一种情况:一组向量
std::vector<double> ac[10] = std::vector<double>(3, 0.5) …Run Code Online (Sandbox Code Playgroud) 我想使用别名std::initializer_list代替自己:
#include<initializer_list>
template< typename T >
using InitializerList = std::initializer_list<T>;
// note: candidate template ignored: couldn't infer template argument 'T'
template< typename T >
void f(InitializerList<T> list) {
}
int main() {
// error: no matching function for call to 'f'
f({1, 2, 3, 4, 5});
}
Run Code Online (Sandbox Code Playgroud)
使用gcc&cl,该代码很好.但是,使用clang我收到错误:
<source>:11:3: error: no matching function for call to 'f'
f({1, 2, 3, 4, 5});
^
<source>:7:6: note: candidate template ignored: couldn't infer template argument 'T'
void f(InitializerList<T> list) {
^ …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 clang 的地址清理程序编译 C++ 以在核心转储中输出清理结果,所以我添加了:
CXXFLAGS += -fsanitize=address
Run Code Online (Sandbox Code Playgroud)
有编译器选项:
/opt/llvm-3.8.0/bin/clang++ --gcc-toolchain=/opt/gcc-5.2.0 -fsanitize=address -DLINUX -DLINUX64 -DTB_USE_RCU -DURCU_INLINE_SMALL_FUNCTIONS -DU_USING_ICU_NAMESPACE=0 -DNDEBUG -D_POSIX_PTHREAD_SEMANTICS -fPIC -D_GNU_SOURCE -DTB_USE_RCU -DTB_USE_RCU -D_GLIBCXX_USE_CXX11_ABI=0 -m64 --gcc-toolchain=/opt/gcc-5.2.0 -flto=full -std=gnu++14 -D_GLIBCXX_DEPRECATED= -pipe -fno-omit-frame-pointer -ffast-math -fno-finite-math-only -pthread -march=core2 -mtune=corei7 -g -O3 -Qunused-arguments -fnon-call-exceptions -fvisibility=hidden -fvisibility-inlines-hidden -Wall -Wextra -Wshadow -Wpointer-arith -Wno-self-assign -Wno-unused-function -Wno-gnu-empty-initializer -Wno-unused-parameter -Wno-ignored-qualifiers -Wno-mismatched-tags -Wno-unused-local-typedef -Wno-parentheses-equality -Wno-unused-private-field -Wno-missing-field-initializers -Wno-missing-braces -Werror=return-type -Werror=overloaded-virtual -c MyClass.cpp -o MyClass.o
Run Code Online (Sandbox Code Playgroud)
但我收到错误:
undefined symbol: __asan_option_detect_stack_use_after_return
Run Code Online (Sandbox Code Playgroud)
解决这个问题的最简单方法是什么?
我正在尝试摆脱有损隐式转换的代码库,因此正在使用-Wconversionclang ++下的标记进行编译。以下代码预期会输出警告,但不会输出。
#include <cstddef>
#include <iostream>
#include <limits>
#include <optional>
int main() {
size_t x = std::numeric_limits<size_t>::max();
std::cout << x << std::endl;
auto x2 = std::make_optional<uint8_t>(x);
std::cout << (int)*x2 << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在make_optional生产线上,我size_t无声地缩小为a uint8_t。uint8_t x2 = x;例如,如果我写,我得到了预期的缩小转换警告。
当我使用std::optional构造函数时,也会发生这种情况。在我给出的代码中,调用了make_optional重载2,该调用调用了可选的构造函数重载6。这构造了Optional,就好像直接初始化包含的值一样,并且直接初始化不会引发隐式变窄转换警告。
除了编写optional自己的不隐藏缩小转换的类之外,还有什么方法可以使上述代码引发缩小转换警告?
以下代码不能在 clang 中编译(在 GCC 中可以):
struct A{
int a;
};
auto test(){
constexpr A x{10};
return []{
return x; // <-- here x is A: clang doesn't compile
}();
}
Run Code Online (Sandbox Code Playgroud)
Clang 的错误是变量 'x' 不能在没有指定捕获默认值的 lambda 中隐式捕获,但我认为 constexpr 变量总是被捕获。
如果 x 是 int,则代码编译:
auto test(){
constexpr int x{10};
return []{
return x; // <-- here x is int: clang is ok
}();
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,以下代码也可以编译:
auto test(){
constexpr A x{10};
return []{
return x.a;
}();
}
Run Code Online (Sandbox Code Playgroud)
叮当正确吗?如果是这样,理由是什么?我正在使用 -std=c++17
- 编辑 …