C++标准说明了关于等于运算符的以下内容==:
[C++11: 5.10/1]:[..]相同类型的两个指针比较相等,当且仅当它们都为空时,都指向相同的函数,或者两者都表示相同的地址.
我的初步解释是函数本身在语义上没有"地址"本身,因此"或两者代表相同的地址"只能用于引用对象,而不是函数.否则为什么要打扰"指向同一个功能"条款呢?
也就是说,当且仅当两者都指向相同的函数period时,相同类型的两个函数指针才相等.
这样做的结果是在这个问题中看到的行为(指向两个不同但相同的函数的指针具有相同的值)将是一个实现错误,因为指向不同函数的指针将是唯一的.
我觉得,这是该条款的意图,但我不能找到一种方法来客观地捍卫的观点,这是何等的通道的意思实际上应该推断,或者它真的是委员会的意图,现在我的解释已经成为问题:
[D]跟我说"[...]或两者代表同一个地址." 不满足于Visual C++的行为.(@jstine)
所以我的问题是关于这个标准段落的意图.
或者:
我在正确的轨道上:函数指针必须比较相等,如果它们都指向相同的函数("地址"被诅咒),或者
通道中有一个冗余:函数指针必须比较相等,如果它们都指向同一个函数或两者都代表相同的地址; 并且,通过扩展,允许实现使两个函数存在于同一地址.
这是什么?
是否可以获取通过ADL找到的函数的地址?
例如:
template<class T>
void (*get_swap())(T &, T &)
{
return & _________; // how do I take the address of T's swap() function?
}
int main()
{
typedef some_type T;
get_swap<T>();
}
Run Code Online (Sandbox Code Playgroud) 考虑以下代码:
template<typename T>
struct A
{
void f(){...}
friend T;
};
template<typename T>
struct B
{
void f(T){...}//code depends on T
void g(){...}//code doesn't depends on T
}
Run Code Online (Sandbox Code Playgroud)
如您所见,"代码"中的"代码" struct A不依赖于T.编译器是否会在每个T用于实例化的最终二进制文件中生成不同的代码A?
同样的B::g()功能问题,编译器是否会在B<T>可能的情况下对所有实例使用相同的函数,例如this未使用g(),因此不依赖于T?该标准是否有针对此案例的任何规范?
[注意:这是从https://softwareengineering.stackexchange.com/q/369604/126197转发的,由于某种原因,这个问题立即被低估了.两次.显然,这里有更多的爱!]
这是从供应商的例子中解释的一些代码.
我已经找了关于按值传递堆栈分配结构的权威文档,但是没有找到确定的单词.简而言之:C99是否保证这是安全的?
typedef struct {
int32_t upper;
int32_t lower;
} boundaries_t;
static boundaries_t calibrate() {
boundaries_t boundaries; // struct allocated on stack
boundaries.upper = getUpper();
boundaries.lower = getLower();
return boundaries; // return struct by value
}
int main() {
boundaries_t b;
b = calibrate();
// do stuff with b
...
}
Run Code Online (Sandbox Code Playgroud)
请注意,在堆栈上calibrate()分配boundaries结构,然后按值返回它.
如果编译器可以保证堆栈帧calibrate()在赋值时保持不变b,那么一切都很好.也许这是C99的价值合约中的合同的一部分?
(上下文:我的世界是很少见到传值的嵌入式系统.我知道从堆栈分配的结构中返回一个指针是灾难的一个方法,但这个传值的东西感觉很陌生.)
到目前为止我读过的所有书籍中,他们都说 C++ 模板为我们使用的每种类型生成一个代码实例。
另一方面,书上说在 C# 中代码是重用的。
因此,我在许多书籍中进行了搜索,并在一本很旧的书中找到了以下 C# 示例。
1) 值类型
List<int> intList1 = new List<int>();
List<int> intList2 = new List<int>();
List<bool> boolList = new List<bool>();
Run Code Online (Sandbox Code Playgroud)
在这种情况下(值类型),编译器为 intList1 和 intList2(相同类型)生成一个代码实例,并为 boolList 生成一个代码实例。
2) 参考类型
List<Dog> dogList1 = new List<Dog>();
List<Dog> dogList2 = new List<Dog>();
List<Cat> catList = new List<Cat>();
Run Code Online (Sandbox Code Playgroud)
在这种情况下(引用类型),编译器只为dogList1、dogList1和catList生成一个代码实例,因为只要它可以表示指向对象的指针,所有引用类型都可以共享一个实现。
这对我(作为 C++ 开发人员)来说非常清楚,但我对有关 C++ 模板的同样的事情感到好奇。
早在 C# 创建之前,C++ 也有值类型和引用类型。
因此,让我们用 C++ 重写 avove 示例
1) 值类型
vector<int> intList1;
vector<int> intList2;
vector<bool> boolList;
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我毫不怀疑 intList1 和 intList2 共享相同的代码,并且 boolList 需要另一个实现
2) …
我需要帮助从反汇编逆向工程虚拟方法.该代码最初使用Microsoft的Visual C++编译.有问题的方法如下:
sub_92D110 proc near
xor al, al
retn
sub_92d110 endp
Run Code Online (Sandbox Code Playgroud)
这个方法在很多类之间引用,甚至在一个类的vtable内多次引用.我不确定它的作用; 这是否意味着该方法被内联,但调用仍然保持vtable保持其大小?
如果是这样,那该怎么xor al, al办?我是否误解了召唤大会或其他什么?