小编ana*_*lyg的帖子

与位置无关的代码和vtable

虚拟函数如何在与位置无关的代码中实现?

我知道如果我的类有虚函数,编译器通常会为它生成一个包含所有虚函数地址的vtable,并在我的类的每个对象中存储一个指向vtable的指针.

现在,如果我的代码与位置无关,则编译器无法知道虚函数的地址(或任何函数).那它是做什么的?

我想知道真正的编译器是做什么的(不是理论上可行的); 我最感兴趣的是Linux 32位平台,但其他平台也有点有趣.

c++ gcc virtual-functions dynamic-linking vtable

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

我应该如何在C结构中声明字符串?

您好我是这个网站的新手,我需要一些帮助来理解在C中编码需要字符串的结构时会被视为"规范"的内容.基本上我想知道在使用C中的结构来跟踪结构所需的所有内存时,下列哪种方式将被视为"行业标准":

1)固定尺寸字符串:

typedef struct
{
    int damage;
    char name[40];
} Item;
Run Code Online (Sandbox Code Playgroud)

我现在可以使用 sizeof(Item)

2)字符数组指针

typedef struct
{
    int damage;
    char *name;
} Item;
Run Code Online (Sandbox Code Playgroud)

我知道我可以存储name使用第二个变量的大小,但还有另一种方法吗?

i)使用固定尺寸是否有任何其他优势(1)

char name[40];
Run Code Online (Sandbox Code Playgroud)

与执行以下操作并使用指向char数组的指针(2)?

char *name;
Run Code Online (Sandbox Code Playgroud)

如果是的话,有什么好处?

ii)此外,字符串是否使用指向char数组(2)的指针将按顺序存储在结构之后(紧接在指向字符串的指针之后),还是存储在内存中的其他位置?

iii)我想知道如何找到char *字符串变量的长度(不使用a size_t或整数值来存储长度)

c arrays string pointers

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

如何有条件地捕获异常?

我的大型应用程序有这种结构:

int main()
{
    try {
        ...
    } catch (std::exception& e) {
        std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
        return 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

在调用堆栈内部,各种对象检查其内部状态,std::runtime_exception如果它们检测到不好的东西则抛出.全包异常处理程序捕获它,打印一些中等有用的信息并终止程序.

但是,当我在MS Visual Studio下调试时,我可以从没有任何异常处理程序中受益:Visual Studio有自己的,非常有用的处理程序,它会在抛出异常的地方停止我的应用程序,所以我可以检查一下出错.

如何有条件地捕获我的异常?

我尝试了以下方法:

    try {
        ...
    } catch (std::exception& e) {
        if (IsDebuggerPresent())
            throw;
        else
            std::cout << "Fatal error: " << e.what() << (some more data) << std::endl;
    }
Run Code Online (Sandbox Code Playgroud)

这给出了一个奇怪的结果:Visual Studio捕获了重新抛出的异常,并向我展示了抛出异常的位置的堆栈跟踪.但是,我的应用程序中的所有对象显然都被破坏了,我看不到例如局部变量或成员变量.

我可以使异常处理程序以编译标志为条件:

#ifdef NDEBUG
    try {
#endif
        ...
#ifdef NDEBUG
    } catch (std::exception& e) { …
Run Code Online (Sandbox Code Playgroud)

c++ debugging exception visual-studio

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

声明模板类成员和构造函数时的C++习语

虽然以下两个编译(使用Visual Studio 2013),其中一个更加"正确"的C++习语?在调用基类构造函数和声明成员时,我特别谈到显式模板参数.标准是否对此有看法?有一个很好的实际理由偏爱一个而不是另一个吗?

template<class T>
class Bar1 : public Base<T>
{
public:

    Bar1() : Base() {}
    Bar1(T value) : Base(value) {}
    Bar1(Bar1 const & other) : Base(other.value) {} 

    void Foo(Bar1 const & other)
    {
        // Some foo related activity.
    }
};

template<class T>
class Bar2 : public Base<T>
{
public:

    Bar2() : Base<T>() {}
    Bar2(T value) : Base<T>(value) {}
    Bar2(Bar2<T> const & other) : Base<T>(other.value) {}

    void Foo(Bar2<T> const & other)
    {
        // Some foo related activity.
    }
};
Run Code Online (Sandbox Code Playgroud)

c++ syntax templates visual-studio

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

为什么 atan2(y,x) 的计算速度比 arcsin 或 arccos 更快?

我读过,当我知道 Y 和 X 时,最好通过计算atan2(y,x)来获取角度,而不是使用带有 asin 和 acos 的单个值。我试图深入研究math.hlib 但没有找到任何公式。

有人可以解释为什么atan2更好吗?

performance trigonometry

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

从C库调用C++函数指针

我有一个只有静态成员的类.

我想在退出时使用"atexit"库函数注册其成员函数之一(下面的代码中的VerifyClean).

C++常见问题解答说,我必须指定为extern"C"为我要注册这样,就像在下面的例子中的功能.

class Example
{
public:
    static void Initialize();
    static void DoDirtyStuff {++dirtLevel;}
    static void CleanUpStuff {--dirtLevel;}
private:
    static void VerifyClean();
    // DOESN'T COMPILE: extern "C" static void VerifyClean();
    static int dirtLevel;
}

int Example::dirtLevel;

extern "C" void Example::VerifyClean() // DO I NEED extern "C" HERE?
{
    assert(dirtLevel == 0);
}

void Example::Initialize()
{
    dirtLevel = 0;
    atexit(&VerifyClean);
}
Run Code Online (Sandbox Code Playgroud)

我真的必须使用extern"C"吗?

如果我将"atexit"替换为非库函数(在纯C中实现),答案是否会改变?

如果函数VerifyClean是公共的,我决定直接从C++代码调用它,我会得到链接错误或运行时崩溃吗?我问这个是因为声明根本没有提到extern"C",所以常规的C++代码可能会错误地处理函数调用.这在我的MS Visual Studio 2005系统上运行正常.

c++

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

将int赋值给short(gcc)时没有警告

我经常使用"较长"类型变量赋值为"较短"变量,例如intto shortuint32_tto uint8_t.有一天,我决定使用gcc在我的代码中找到所有这些情况,但令我惊讶的是gcc没有输出任何警告!

int long_value;
short short_value;
std::cin >> long_value; // Example input: 32769
short_value = long_value; // MS Visual Studio complains here at warning level 4
std::cout << "Long: " << long_value << '\n'; // My example output: 32769
std::cout << "Short: " << short_value << '\n'; // My example output: -32767
Run Code Online (Sandbox Code Playgroud)

使用gcc -Wallgcc -Wconversion没有帮助(gcc没有输出任何警告).实际上,它从不输出任何输入和输出类型的警告(例如longunsigned char).

我从未在gcc中发现过一个真正的错误,所以我几乎可以肯定这种行为是有道理的.

那么为什么没有警告?

更新:我使用gcc 4.1.2.

c++ gcc compiler-warnings implicit-conversion

5
推荐指数
2
解决办法
2797
查看次数

根据平台选择功能名称的最标准方法是什么?

我目前正在使用popen由两个编译器编译的代码中的函数:MS Visual Studio和gcc(在linux上).我可能想稍后添加gcc(在MinGW上).

该函数被调用popen为gcc,但_popen对于MSVS,所以我在源代码中添加了以下内容:

#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif
Run Code Online (Sandbox Code Playgroud)

这是有效的,但我想了解是否存在针对此类问题的标准解决方案(我记得与stricmp/ 的类似情况strcasecmp).具体来说,我想了解以下内容:

  1. _MSC_VER正确的旗帜依赖吗?我选择它是因为我觉得linux环境"更标准".
  2. 如果我把它们#define放在一些头文件中,那么#include它是在之前还是之后stdio.h(对于这种情况popen)是否重要?
  3. 如果_popen被定义为宏本身,我有可能#define失败吗?我应该使用"新"代币my_popen,因为这个或那个原因?
  4. 有人已经为我做了这个工作,并制作了一个很好的"可移植头"文件,我可以使用?
  5. 还有什么我应该知道的吗?

c portability popen

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

如何有效地定义128位常量?

我正在使用MS Visual Studio中的SSE2指令集.我用它来做16位数据的计算.

假设我有8个值加载到SSE寄存器中.我想为42所有这些添加常量(例如).这是我希望我的代码看起来如何.

__m128i values; // 8 values, 16 bits each
const __m128i my_const_42 = ???; // What should i write here?
values = _mm_add_epi16(values, my_const_2); // Add 42 to the 8 values
Run Code Online (Sandbox Code Playgroud)

现在,我该如何定义常数?以下两种方式有效,但一种方法效率低下,另一方面很难看.

  1. my_const_42 = _mm_set_epi16(42, 42, 42, 42, 42, 42, 42, 42) - 编译器生成8个命令来"构建"常量
  2. my_const_42 = {42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0, 42, 0} - 很难理解发生了什么; 改变42到如-42不是小事

有没有办法更方便地表达128位常数?

c optimization sse intrinsics visual-studio

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

近似排序算法

有谁知道对数组进行 k 近似排序的算法吗?

我们被要求找到 k 近似排序的算法,它应该在 O(n log(n/k)) 中运行。但我似乎找不到任何。

K-大约。排序意味着数组和任何 1 <= i <= nk 使得 sum a[j] <= sum a[j] i<=j<= i+k-1 i+1<=j<= i+k

arrays sorting algorithm approximation

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