小编phl*_*psy的帖子

函数参数和默认参数的评估顺序

我最近碰到了以下情况:

#include <iostream>

int *p = 0;

int f() {
    p = new int(10);
    return 0;
}

void g(int x, int *y = p) {
    std::cout << y << std::endl;
}

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

这非常微妙,因为您通常不希望默认参数在评估函数调用期间发生变化.我不得不看一下程序集来发现这个错误.

现在我的问题是:这是否真的是未定义的行为,因为对函数参数的评估顺序没有任何保证?

c++ operator-precedence undefined-behavior default-parameters

19
推荐指数
2
解决办法
1502
查看次数

动态加载的库和共享的全局符号

由于我在动态加载的库中观察到了全局变量的一些奇怪行为,因此我编写了以下测试.

首先,我们需要一个静态链接的库:标题 test.hpp

#ifndef __BASE_HPP
#define __BASE_HPP

#include <iostream>

class test {
private:
  int value;
public:
  test(int value) : value(value) {
    std::cout << "test::test(int) : value = " << value << std::endl;
  }

  ~test() {
    std::cout << "test::~test() : value = " << value << std::endl;
  }

  int get_value() const { return value; }
  void set_value(int new_value) { value = new_value; }
};

extern test global_test;

#endif // __BASE_HPP
Run Code Online (Sandbox Code Playgroud)

和来源 test.cpp

#include "base.hpp"

test global_test = test(1);
Run Code Online (Sandbox Code Playgroud)

然后我写了一个动态加载的库: library.cpp

#include …
Run Code Online (Sandbox Code Playgroud)

c++ linux g++ cmake shared-libraries

9
推荐指数
1
解决办法
9248
查看次数

const基类的效果

以下构造的实际效果是什么:

class Base { /* ... */ };

template<class T>
class Derived : public T { /* ... */ };

int main() {
    Derived<const Base> d;
    // ...
}
Run Code Online (Sandbox Code Playgroud)

Derived该类是否只能访问const接口的-part Base?我的第一次测试表明实际上根本没有效果.为什么?

谢谢!

c++ const derived-class

9
推荐指数
1
解决办法
903
查看次数

内联模板功能的可见性

编译事实背后的理性是什么?

namespace ns __attribute__((visibility("default"))) {

template<typename T>
inline int func1(const T& x) {
    return x;
}

inline int func2(int x) {
    return x;
}

struct test {
    template<typename T>
    int func3(const T &x) { return x; }

    int func4(int x) { return x; }
};

}

int __attribute__((visibility("default"))) client(int x) {
    ns::test t;
    const int y1 = ns::func1(x);
    const int y2 = ns::func2(x);
    const int y3 = t.func3(x);
    const int y4 = t.func4(x);
    return y1 + y2 + y3 + …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates visibility elf

9
推荐指数
1
解决办法
330
查看次数

为什么不叫我的新操作员

我想看到一个动态加载的库(加载了dlopen等)确实使用了自己的新的删除操作符而不是调用程序中定义的那些操作符.所以我写了下面的library.cpp

#include <exception>
#include <new>
#include <cstdlib>
#include <cstdio>
#include "base.hpp"
void* operator new(size_t size) {
    std::printf("New of library called\n");
    void *p=std::malloc(size); 
    if (p == 0) // did malloc succeed?
        throw std::bad_alloc(); // ANSI/ISO compliant behavior
    return p;
}
void operator delete(void* p) {
    std::printf("Delete of library called\n");
    std::free(p);
}
class Derived : public Base {
public:
    Derived() : Base(10) { }
};
extern "C" {
    Base* create() {
        return new Derived;
    }
    void destroy(Base* p) {
        delete p;
    } …
Run Code Online (Sandbox Code Playgroud)

c++ overriding allocation g++

8
推荐指数
1
解决办法
3449
查看次数

将前向声明的C-struct定义为C++ - struct

将a struct作为C- 转发声明是否合法struct

// api.h
#ifdef __cplusplus
extern "C" {
#endif

    typedef struct handle_tag handle_t;

    handle_t *construct();
    void destruct(handle_t *h);

    void func(handle_t *h);

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

然后将其定义为C++ - struct即作为非POD类型?

// api.cpp
struct handle_tag {
    void func();
    std::string member;
};

void func(handle_t *h) {
    h->func();
}
Run Code Online (Sandbox Code Playgroud)

一般意图是通过C接口获得外部可访问的opaque类型handle_t,该类型在内部实现为C++数据类型.

c c++ forward-declaration

8
推荐指数
1
解决办法
1336
查看次数

前向声明的类的成员函数指针

common.h向前声明一个类Test和一个接收成员函数指针的函数:

class Test;

void func(const Test &t, int (Test::*f)() const, int x, int y);
Run Code Online (Sandbox Code Playgroud)

在源文件中target.cpp,我定义了这样的函数

#include "common.h"

void func(const Test &t, int (Test::*f)() const, int x, int y) {
    std::cout << "f: " << (t.*f)() << ", x: " << x << ", y: " << y << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

在我的主文件中,我定义了类Test并使用了该函数func:

class Test {
public:
    int example() const { return 1; }
};

#include "common.h"

int main() {
    Test t; …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior visual-c++

7
推荐指数
1
解决办法
450
查看次数

为什么我应该用c ++而不是c来设置插件接口

由于我之前的 问题,我问自己:为插件系统设置C++接口是否有用?以下几点是针对它的:

  • 不同编译器及其版本之间没有共同的ABI,内存中没有对象的共同布局
  • 没有直接的班级出口.你必须出口工厂和析构工具.如果您的对象由仅包含delete它们的其他对象(例如智能指针)保持,则会出现问题.
  • STL的不同实现,你不能传递std::list<T>给插件
  • 不同版本的二手库,如Boost

如果你克制自己的C++语言的其余部分,你几乎最终得到"C子集".有没有关于使用C++的观点?Qt-Toolkit如何解决上述问题?

备注:我主要指的是Linux系统.不过我对其他平台上的解决方案感兴趣.

其他问题:使用C接口有什么问题?structs 的内存布局?应该避免C的哪些语言部分?

c c++ plugins

6
推荐指数
1
解决办法
956
查看次数

rpath在库中的传播失败

简短问题:LC_RPATH库中命令的rpath是否传递到后续(和间接)动态加载的库中?

更确切地说:我已libapi.dylib动态链接到libloader.dylib动态加载插件libplugin.dylib.我有:

$ otool -l lib/libapi.dylib
lib/libapi.dylib
        libapi.dylib
        /usr/lib/libSystem.B.dylib
        @rpath/libloader.dylib

$ otool -l lib/libloader.dylib
lib/libloader.dylib
        libloader.dylib
        /usr/lib/libSystem.B.dylib

$ otool -l lib/plugins/libplugin.dylib
lib/plugins/libplugin.dylib:
        libplugin.dylib
        /usr/lib/libSystem.B.dylib
        @rpath/libloader.dylib

$ otool -L lib/libapi.dylib | grep "LC_RPATH" -A2
        cmd LC_RPATH
      cmdsize 32
        path @loader_path/ (offset 12)
Run Code Online (Sandbox Code Playgroud)

既不定义rpath命令libloader.dylib也不libplugin.dylib定义.并且安装名称没有任何@ rpath /或其他路径,尽管load命令中的名称前缀为@rpath /.

客户端现在加载libapi.dylib哪个链接到哪个libloader.dylib.此库动态加载libplugin.dylib链接到的库libloader.dylib.

为什么不能libplugin.dylib加载?它退出,因为它找不到libloader.dylib- 虽然它必须已经加载.为什么rpath @ loader_path/libapi.dylib没有正确地传播libloader.dyliblibplugin.dylib …

macos mach-o rpath dyld

6
推荐指数
0
解决办法
427
查看次数

将分支移动到历史记录中的另一个点

我们有以下历史

start         master  public
|                 |   |
v                 v   v
o---o-- ... --o---o---o
Run Code Online (Sandbox Code Playgroud)

不幸的是,我们在master包含一些敏感数据的分支中做了一些提交.我们在一个名为public的独立分支中进行了修改.现在我们想要"切断" public分支,以获得一个完整而干净的"状态",public但没有妥协的历史部分仍然包含在内master.换句话说,我们想要以下新历史:

start         master
|                 |
v                 v
o---o-- ... --o---o
 \
  o <- public
Run Code Online (Sandbox Code Playgroud)

现在退房public将导致与原始情况相同的工作树,但没有合理的历史细节.然后我们将旧分支停止master:将其重命名为unsafe并从新master分支中精心设计一个新public分支.通过这种方式,我们保留了旧的历史,unsafe并且能够public毫无后顾之忧地将分支机构推向公众:

start         unsafe
|                 |
v                 v
o---o-- ... --o---o
 \
  o---o-- ... --o <-- public
   \           /
    o-- .. --o-- ... --o <-- master
Run Code Online (Sandbox Code Playgroud)

有什么正确的git命令来实现这一目标?

PS:当然我们可以结账start,建立一个新的分支并在那里提交分支的整个工作树public.但必须有一种不同的,更加迷人的git方式!

git branch

5
推荐指数
1
解决办法
1801
查看次数

在哪里为tr1 :: array添加重载运算符?

因为我需要operator&std::tr1::array<bool, N>我写下以下几行

template<std::size_t N>
std::tr1::array<bool, N>
operator& (const std::tr1::array<bool, N>& a,
           const std::tr1::array<bool, N>& b)
{
  std::tr1::array<bool, N> result;
  std::transform(a.begin(), a.end(), b.begin(), result.begin(),
                 std::logical_and<bool>());
  return result;
}
Run Code Online (Sandbox Code Playgroud)

现在我不知道我要把这个函数放在哪个命名空间中.我认为std命名空间是一个限制区域.用户只允许添加完全特化和重载的功能模板.将它放入全局命名空间不是"允许",以防止污染全局命名空间和与其他声明冲突.最后将此函数放入项目的命名空间不起作用,因为编译器不会在那里找到它.

我最擅长的是什么?我不想写一个新的数组类放入项目命名空间.因为在这种情况下,编译器将通过参数依赖名称查找找到正确的命名空间.或者这是唯一可行的方法,因为为现有类编写一个新的运算符意味着扩展它们的接口,这对于标准类也是不允许的?

c++ namespaces operator-overloading

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

DLL 导出和虚拟方法

在Windows项目中我们定义一个接口类

class Interface {
public:
    virtual ~Interface() { }
    virtual void func() = 0;
};
Run Code Online (Sandbox Code Playgroud)

和一个工厂函数

__declspec(dllexport) Interface *construct();
Run Code Online (Sandbox Code Playgroud)

在 DLL 内。Interface当然,DLL 内部有具体的专门化,但我们不导出它。不过我们可以在 DLL 之外使用它。这是如何运作的?vftable由 构造的实例由construct()指向 DLL 未导出的函数的函数指针组成。这种方法可以接受还是或多或少是一种黑客行为?

abstract-class dllexport visual-c++

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

Binder和可变参数模板最终出现在分段错误中

我写了以下程序

#include <iostream>
template<typename C, typename Res, typename... Args>
class bind_class_t {
private:
  Res (C::*f)(Args...);
  C *c;
public:
  bind_class_t(Res (C::*f)(Args...), C* c) : f(f), c(c) { }
  Res operator() (Args... args) {
    return (c->*f)(args...);
  }
};

template<typename C, typename Res, typename... Args>
bind_class_t<C, Res, Args...>
bind_class(Res (C::*f)(Args...), C* c) {
  return bind_class<C, Res, Args...>(f, c);
}

class test {
public:
  int add(int x, int y) {
    return x + y;
  }
};

int main() {
  test t;
  // bind_class_t<test, int, …
Run Code Online (Sandbox Code Playgroud)

c++ gcc templates variadic

0
推荐指数
1
解决办法
172
查看次数