我想了解为什么编译器允许以下代码进行编译
#include <iostream>
struct A
{
A()
{
std::cout << "A::A\n";
}
virtual void f() const = 0;
};
void g(const A& a)
{
a.f();
}
int main()
{
g({});
}
Run Code Online (Sandbox Code Playgroud)
它甚至A::A在运行时输出.
如果我更换g({})与g(A())它显然不会编译.它抱怨它A是抽象的,无法实例化.Clang和GCC都在没有任何警告的情况下编译此罚款.运行时,两个版本都打印pure virtual method called并终止.
考虑一下这段C++代码:
namespace
{
void f()
{
}
class A
{
void f()
{
::f(); // VC++: error C2039: 'f' : is not a member of '`global namespace''
}
};
}
Run Code Online (Sandbox Code Playgroud)
GCC编译就好了.Visual C++ 2008无法编译吐出C2039错误.这两个编译器中的哪一个在这里是正确的?有没有办法正确引用"全球" f?
编辑: Zack建议尝试,它适用于两个编译器.看起来有点奇怪.
namespace
{
void f()
{
}
class A
{
void f();
};
}
void A::f()
{
::f();
}
Run Code Online (Sandbox Code Playgroud) 我注意到可以const在函数声明中出现值参数的限定符,然后在定义中省略.这不会改变函数的签名.它实际上编译得很好.
我还注意到常规类和模板类之间的行为是不同的.GCC和Clang的处理方式也有区别.
请考虑以下代码:
template <typename T> struct A {
void f(const int);
};
template <typename T> void A<T>::f(int x) {
x = 0;
}
struct B {
void f(const int);
};
void B::f(int x) {
x = 0;
}
void f() {
A<float> a;
a.f(0);
B b;
b.f(0);
}
Run Code Online (Sandbox Code Playgroud)
当我使用GCC编译时,我没有错误.有了Clang我得到:
test.cpp:10:7: error: read-only variable is not assignable
x = 0;
~ ^
test.cpp:26:7: note: in instantiation of member function 'A<float>::f' requested here
a.f(0);
^
Run Code Online (Sandbox Code Playgroud)
海湾合作委员会在定义中优先考虑限定词.Clang使用了声明,仅用于模板类A.
我的问题是: …
有时我看到一些应用程序允许自己在Windows上作为服务运行,例如Apache HTTP Server 允许这样做.我总是将它作为常规应用程序运行,从未遇到任何问题或限制.
我在gcc.godbolt.org上玩GCC反汇编程序,我注意到GCC启动版本4.6编译乘法的方式不同.我有以下两个功能:
unsigned m126(unsigned i)
{
return i * 126;
}
unsigned m131(unsigned i)
{
return i * 131;
}
Run Code Online (Sandbox Code Playgroud)
m126 编译成:
mov eax, edi
mov edx, 126
imul eax, edx
ret
Run Code Online (Sandbox Code Playgroud)
并m131编译成:
imul eax, edi, 131
ret
Run Code Online (Sandbox Code Playgroud)
为什么有区别?GCC 4.5在两种情况下都生成相同的操作码.
我有一个正在后台线程上执行的方法.从那个方法我试图dispatch_async在主线程上的块.该块使用本地C++对象,该对象应该根据Apple参考进行复制.我得到了一个分段错误,从跟踪中我看到一些非常粗略的事情正在发生.这是我的代码的简化版本.
struct A
{
A() { printf("0x%08x: A::A()\n", this); }
A(A const &that) { printf("0x%08x: A::A(A const &%p)\n", this, &that); }
~A() { printf("0x%08x: A::~A()\n", this); }
void p() const { printf("0x%08x: A::p()\n", this); }
};
- (void)runs_on_a_background_thread
{
A a;
a.p();
dispatch_async(dispatch_get_main_queue(), ^{
printf("block begins\n");
a.p();
printf("block ends\n");
});
}
Run Code Online (Sandbox Code Playgroud)
这是输出:
0xbfffc2af: A::A()
0xbfffc2af: A::p()
0xbfffc2a8: A::A(A const &0xbfffc2af)
0x057ae6b4: A::A(A const &0xbfffc2a8)
0xbfffc2a8: A::~A()
0xbfffc2af: A::~A()
0xbfffdfcf: A::A(A const &0x57ae6b4)
0xbfffdfcf: A::~A()
block begins …Run Code Online (Sandbox Code Playgroud) 我遇到了std :: set的奇怪行为.
这是代码:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
#include <vector>
#include <set>
using namespace std;
int main(int argc, char *argv[])
{
set<int> b[100];
for (int o=0; o<10; o++)
{
int tt = GetTickCount();
for (int i=0; i<5000000; i++)
{
b[o].insert(i);
}
tt = GetTickCount() - tt;
b[o].clear();
printf("%d\n", tt);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在Windows XP上运行.
这是有趣的部分:第一次打印时间约为3500毫秒,而接下来的时间都超过9000毫秒!为什么会这样?
哦,这只发布在发布版本(-O2优化).
它不会发生在Linux上(在更改代码后进行编译).
还有一件事:当我使用英特尔VTune进行性能分析时运行它总是需要大约3000毫秒,所以它应该是这样的.
更新:这是一些新代码:
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
const int count = 10000000;
int …Run Code Online (Sandbox Code Playgroud) 我承认我很难找到合理的描述.我想不出一个能够准确描述我正在寻找什么的好词.也许这可以称为切片迭代器.
假设我有这样的事情:
struct S
{
int i;
char *s;
float f;
};
std::vector<S> v(10);
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是一种构造迭代器的方法,它将指向一个成员S.我希望能够将它传递给类似于std::min_element在每种情况下都不创建谓词的东西.可能看起来像这样的东西:
std::min_element(slicing_iterator(v.begin(), S::f), slicing_iterator(v.end(), S::f));
Run Code Online (Sandbox Code Playgroud)
有没有我可以用来实现这个的模板技巧?或许它已经在Boost或其他一些图书馆的某个地方完成了?
我偶然发现了Convert.FromBase64String.NET 4.7.2中的一种奇怪行为。通常,当填充不正确时,它将引发异常。但是我发现添加其他填充字符会产生错误结果而不是异常的情况。
var correct = Convert.FromBase64String("YWE=");
Run Code Online (Sandbox Code Playgroud)
在这种情况下correct为[97, 97]或"aa"为字符串形式。但是当我添加另一个=:
var incorrect = Convert.FromBase64String("YWE==");
Run Code Online (Sandbox Code Playgroud)
而不是得到一个例外,我少了一个字节,并且incorrect是[88]或是"X"字符串形式。
奇怪的。这是一个错误,应该报告吗?还是已知/记录的行为?我找不到对此的任何引用。
比较Ruby。计算结果为"aa":
Base64.strict_decode64 "YWE="
Run Code Online (Sandbox Code Playgroud)
这引发了一个异常:
Base64.strict_decode64 "YWE=="
ArgumentError: invalid base64
from /usr/local/Cellar/ruby/2.6.1/lib/ruby/2.6.0/base64.rb:74:in `unpack1'
Run Code Online (Sandbox Code Playgroud) 在我运行iOS 4.2.1的iPhone 3G上尝试分配大量内存时,我注意到了一件很奇怪的事情.
当我malloc(512 * 1024)在一个循环中调用它返回一个有效的指针大约1500次之后,我得到一个NULL和
app(2032,0x3e7518b8) malloc: *** mmap(size=524288) failed (error code=12)
*** error: can't allocate region
Run Code Online (Sandbox Code Playgroud)
它让我感到惊讶,因为我认为我的iPhone没有750 MB的RAM.然后,我添加了一个memset后,malloc并把它带到分配到120的数量,这更有道理.
这是我使用的超简单代码:
for (int i = 1; ; ++i)
{
void *p = malloc(512 * 1024);
NSLog(@"%d %p", i, p);
memset(p, 0, 512 * 1024);
}
Run Code Online (Sandbox Code Playgroud)
我虽然iPhone没有任何可以解释类似行为的虚拟内存系统.对此有什么合理的解释?