我在尝试制作常量正确的代码时偶然发现了一个小问题.
我本来想写一个函数,它接受一个const结构的指针,告诉编译器"请告诉我,如果我正在修改结构,因为我真的不想".
我突然想到编译器会允许我这样做:
struct A
{
char *ptrChar;
};
void f(const struct A *ptrA)
{
ptrA->ptrChar[0] = 'A'; // NOT DESIRED!!
}
Run Code Online (Sandbox Code Playgroud)
这是可以理解的,因为实际上const是指针本身,而不是它指向的类型.我想让编译器告诉我,我正在做一些我不想做的事情,但是,如果可能的话.
我使用gcc作为我的编译器.虽然我知道上面的代码应该是合法的,但我仍然检查它是否会发出警告,但没有任何结果.我的命令行是:
gcc -std=c99 -Wall -Wextra -pedantic test.c
Run Code Online (Sandbox Code Playgroud)
有可能解决这个问题吗?
我做了这个简单的课程,仍然在玩我的想法:
class A {
private:
class B {};
public:
B getB() {
return B();
};
};
Run Code Online (Sandbox Code Playgroud)
从C++ 03开始,这个类编译得很好,但是没有很好的方法可以将结果分配给getB()左值,在这个意义上:
A::B b = A().getB();
Run Code Online (Sandbox Code Playgroud)
不编译.
我通过使用中间模板得到它,以这种方式:
template <typename T>
struct HideType {
typedef T type;
};
HideType<A::B>::type b = A().getB();
Run Code Online (Sandbox Code Playgroud)
但这看起来很糟糕,因为这个简单的任务是得到一个A :: B左值变量.
从C++ 11开始就不再这样了,或者至少它不适用于gcc.此代码仍无效:
A::B b = A().getB();
Run Code Online (Sandbox Code Playgroud)
但这是有效的:
auto b = A().getB();
Run Code Online (Sandbox Code Playgroud)
标准方面是否存在漏洞?
我想知道在C或C ++中使用浮点运算的任何代码在任何基于x86的体系结构中是否都会产生精确的结果,而不管代码的复杂性如何。
据我所知,自从Intel 8087开始,任何x86架构都使用了准备处理IEEE-754浮点数的FPU单元,而且我看不出任何原因导致不同架构的结果不同。但是,如果它们不同(即由于不同的编译器或不同的优化级别),那么是否有某种方法可以通过仅配置编译器来产生位精确结果?
C++标准允许将const引用绑定到rvalues,从而延长临时的生命周期,直到引用超出范围.但是,我无法弄清楚这是如何实际编译的,让我用一个例子来解释:
std::string foo() {
return std::string("foo");
}
void bar() {
VeryBigObject obj;
// Perhaps do something with the big object
}
int main(int, char **) {
const std::string &foo_str = foo();
bar();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,使用x86架构作为例子,首先foo()调用函数并在堆栈中构造字符串对象,这意味着从rsp寄存器中减去所需的空间量(假设为64)位结构); 之后,rsp寄存器返回其原始值,释放函数foo()正在填充的堆栈空间,如果我理解正确,调用bar()将使用该堆栈空间来构造VeryBigObject,这将覆盖该字符串.
考虑到所有这些,在调用foo()汇编域后,如何延长字符串的生命周期?
在编写正常编译的有效C++ 03模板代码时,我遇到了一个小的(很容易解决的)问题,在使用C++ 11方言时无法编译.
问题出现在模板参数分辨率上.让这段代码成为一个例子:
template <uint32_t number>
struct number_of_bits {
enum {
value = 1 + number_of_bits<number >> 1>::value
};
};
template <>
struct number_of_bits<0> {
enum {
value = 0
};
};
Run Code Online (Sandbox Code Playgroud)
由于C++ 11现在允许">>"完成一个模板参数列表,该列表将模板化参数作为最后一个参数,因此在解析此代码时会产生问题.
我使用GCC(版本4.8.1)作为我的编译器,它使用命令行正常编译:
g++ test.cc -o test
Run Code Online (Sandbox Code Playgroud)
但是当我添加-std=c++11命令行开关时它无法编译:
g++ -std=c++11 test.cc -o test
Run Code Online (Sandbox Code Playgroud)
这是一个C++ 11语言功能还是GCC中的一个错误?这是一个已知的错误,如果是这样的话?
我观察到当某个类的方法被标记为final在C++ 11中时,vtable中没有查找来调用该方法,即使是从指针调用,至少使用GCC生成的程序集.让这段代码作为例子:
class Base {
public:
Base() : retval(0) {}
virtual ~Base(){}
virtual int method() {
return retval;
}
protected:
uint32_t retval;
};
class DerivedFinal : public Base {
public:
int method() final {
return retval + 2;
}
};
int main() {
Base *bptr = new Base();
DerivedFinal *df = static_cast<DerivedFinal *>(bptr);
return df->method();
}
Run Code Online (Sandbox Code Playgroud)
请注意,代码使用这样的返回值来使汇编代码易于阅读.
主要的装配看起来像这样:
<+0>: push %rbp
<+1>: mov %rsp,%rbp
<+4>: push %rbx
<+5>: sub $0x18,%rsp
<+9>: mov $0x10,%edi
<+14>: callq 0x400750 <_Znwm@plt>
<+19>: …Run Code Online (Sandbox Code Playgroud)