如果给函数参数添加了注释ERROR: Command errored out with exit status 1:
command: /usr/local/bin/python3.6 /usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /tmp/tmplcfg2oqe
cwd: /tmp/pip-install-o7_ciep3/PyQt5
Complete output (37 lines):
Querying qmake about your Qt installation...
/usr/bin/qmake -query
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 103, in prepare_metadata_for_build_wheel
hook = backend.prepare_metadata_for_build_wheel
AttributeError: module 'sipbuild.api' has no attribute 'prepare_metadata_for_build_wheel'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 257, in <module>
main()
File "/usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 240, in main
json_out['return_val'] = hook(**hook_input['kwargs'])
File "/usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 108, in prepare_metadata_for_build_wheel
config_settings)
File "/usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py", line 136, in _get_wheel_metadata_from_wheel
whl_basename = backend.build_wheel(metadata_directory, config_settings)
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/sipbuild/api.py", line 51, in build_wheel
project = AbstractProject.bootstrap('pep517')
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/sipbuild/abstract_project.py", line 82, in bootstrap
project.setup(pyproject, tool, tool_description)
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/sipbuild/project.py", line 410, in setup
self.apply_user_defaults(tool)
File "project.py", line 62, in apply_user_defaults
super().apply_user_defaults(tool)
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/pyqtbuild/project.py", line 86, in apply_user_defaults
super().apply_user_defaults(tool)
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/sipbuild/project.py", line 215, in apply_user_defaults
self.builder.apply_user_defaults(tool)
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/pyqtbuild/builder.py", line 76, in apply_user_defaults
self._get_qt_configuration()
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/pyqtbuild/builder.py", line 436, in _get_qt_configuration
for line in project.read_command_pipe([self.qmake, '-query']):
File "/tmp/pip-build-env-h65hqnoo/overlay/lib/python3.6/site-packages/sipbuild/project.py", line 374, in read_command_pipe
"'{0}' failed returning {1}".format(cmd, pipe.returncode))
sipbuild.exceptions.UserException
----------------------------------------
ERROR: Command errored out with exit status 1: /usr/local/bin/python3.6 /usr/local/lib/python3.6/site-packages/pip/_vendor/pep517/_in_process.py prepare_metadata_for_build_wheel /tmp/tmplcfg2oqe Check the logs for full command output.
,而我尝试在函数主体中进行const int &x
,则会收到编译时错误,该错误用于修改只读引用。但是,如果我像这样使用x++
修饰符:
__restrict__
...我没有得到编译时错误。如果我未优化地运行此代码,则输出为void foo(int & __restrict__ a, int & __restrict__ b) {
if (a == 1)
b = 2;
if (a == 2)
b = 3;
}
int main() {
int x = 1;
foo(x, x); // should be illegal?
cout << x;
}
,但如果我以3
或更高版本运行,则输出为-O1
。似乎检测到2
要通过两次很简单,并且很容易被禁止。为什么C ++可以防止对x
的滥用,而不能对const
的滥用呢?
答案 0 :(得分:3)
在非常一般的情况下,不可能在编译时对其进行诊断。就像一个简单的反例一样,请考虑:
void foo(int* __restrict__ a, int * __restrict__ b);
int x;
int y;
std::cin >> x >> y;
int* a = (x%2) ? &x : &y;
int* b = (y%2) ? &x : &y;
foo(a,b);
编译器无法知道a
和b
是否指向相同的int
。实际上,如果编译器可以进行这种分析,则不需要__restrict__
限定符,因为这样编译器可以自己确定是否使用了两个指针来访问同一内存。
答案 1 :(得分:3)
您正在向后看__restrict__
。
__restrict__
是一个实现扩展,程序员可以使用它来传达意图,以最大化生成的代码质量和性能(“优化”)。
这不是检查,也不是对程序的限制。
它不是类型系统的一部分,因此也不是函数类型的一部分,因此不能在调用站点上强制执行(通常)。
您用来告诉编译器某些东西,就像其他一些扩展名(例如__builtin_unreachable
)一样。
在这种情况下,您要告诉它“我不是在通过任何其他指针来指望指针”。
您并不是在问它“请阻止我通过任何其他指针来指代指针”。
C和C ++编译器已经在可能的地方执行了强大的“别名”检查。在自动混叠检测无法正常工作的情况下,__restrict__
关键字可以让 you 告诉 it “我确定”。例如翻译单位边界)。由于自动别名检测无法正常工作,因此无法执行__restrict__
。
而且,即使可能,也与修饰符的目的相反。
答案 2 :(得分:2)
通常很难检测到restrict
违规。假设您有一个功能
void bar(int* p1, int* p2) {
foo(*p1, *p2);
}
在这种情况下,编译器应该做什么?
在某些情况下(例如您的示例),可以检测到restrict
违例,并且某些编译器也可以检测到违规。例如,带有-Wrestrict
的GCC会产生警告:
在警告:将参数1传递给带有参数2的限定条件的参数别名
-Wrestrict
上的GCC documentation读取:
当由
restrict
限定的参数(或在C ++中,由__restrict
限定的参数)引用的对象被另一个参数别名时,或当此类对象之间的副本重叠时,会发出警告。
您可以使用-Werror=restrict
选项将此警告变成错误。