在C99中有变长数组,参数数组声明符中可以有静态限定符(和类型限定符):
void f(int i, int *a);
void f(int i, int a[]);
void f(int i, int a[i]);
void f(int i, int a[*]); // Only allowed in function prototypes.
void f(int i, int a[static i]);
Run Code Online (Sandbox Code Playgroud)
由于数组函数参数只是衰减到指针,以前的声明之间是否有任何实际差异,还是风格问题?什么时候应该使用它们?特别是,static限定词意味着什么?该标准没有清楚地说明每种语法的原因.
考虑以下:
template<typename T>
struct C {};
template<typename T, typename U>
void operator +(C<T>&, U);
struct D: C<D> {};
struct E {};
template<typename T>
void operator +(C<T>&, E);
void F() { D d; E e; d + e; }
Run Code Online (Sandbox Code Playgroud)
此代码在GCC-7和Clang-5上编译良好.选定的重载operator +是struct E.
现在,如果发生以下变化:
/* Put `operator +` inside the class. */
template<typename T>
struct C {
template<typename U>
void operator +(U);
};
Run Code Online (Sandbox Code Playgroud)
即,如果operator +被定义内部类模板,代替外,再产生锵歧义之间的两个operator +S出现在代码中.海湾合作委员会仍然编制好.
为什么会这样?这是GCC还是Clang的错误?
我正在编写一个Excel RTD服务器实现,我被困在一个实现的coclass的样板上IDispatch.我无法访问ATL,但我使用的是ActiveQt,虽然我对如何在原始C或C++中执行此操作感兴趣.如何正确实现IDispatchCOM服务器中的方法?
一如既往,文档非常糟糕.到目前为止我所读的内容如下:
IDispatch方法调用委托给某些人ITypeInfo是更好的做法.它是否正确?ITypeInfo自己?LoadTypeLib()和系列(后面看ITypeLib::GetTypeInfo())?这种LoadTypeLib()方法似乎适合COM 客户端访问某些库的类型信息,而不适用于尝试内省自身的COM服务器.我对么?
我目前正在开发一个C项目,需要在不同的建筑环境中相当便携.该项目面向托管C环境中符合POSIX的系统.
实现良好程度的可移植性的一种方法是根据所选标准进行编码,但很难确定给定的翻译单元是否严格符合ISO C.例如,它可能违反某些翻译限制,或者它可能依赖于未定义的行为,而没有来自编译环境的任何诊断消息.我甚至不确定是否有可能检查大型项目的严格一致性.
考虑到这一点,是否有任何编译器,工具或方法在翻译单元的给定标准(例如,C89或C99)下测试严格的 ISO C一致性?
任何帮助表示赞赏.
考虑以下:
namespace N {
extern "C" void f();
}
void g() {
N::f();
}
Run Code Online (Sandbox Code Playgroud)
此代码在命名空间内声明了一个带有C链接的外部函数.这使得可以从私有名称空间引用这样的函数,从而避免由普通的全局外部声明引起的结果名称空间污染.它还允许客户端代码为相同的函数发出其他(希望兼容的)声明而不会发生冲突,即使在全局命名空间中也可能源自供应商提供的头部包含.
我经常依赖C和C++中的类似结构来将编译与一些库提供的错误编写或冲突的头文件隔离开来.(在C中,这是通过在函数范围发出所需的声明来实现的,这在C++中也是可能的,如果不是extern在函数范围内不允许链接声明的话.)这对于正确链接到明确的定义特别有用. ABI无需依赖供应商提供的头文件.
是否可以使用常规C++链接的函数或方法执行相同的操作?那就是:在私有命名空间(或任何类型的本地范围)内声明一个带有C++链接的外部函数,但是它可能是指在另一个命名空间内实际定义的函数?
预期功能(伪代码):
namespace N {
// Actually should link with P::f() (and not N::f()).
extern "C++" void f();
}
void g() {
N::f(); // P::f();
}
Run Code Online (Sandbox Code Playgroud)
对于源文件(与头文件相对),这显然不是问题,因为在这种情况下命名空间污染无关紧要.因此,这个问题主要是指隔离库头文件中的声明(在模板和内联函数中使用).
欢迎编译器特定的解决方案(感兴趣的是MSVC和GCC).
示例:假设我的库被调用Lib1,我想在Lib1命名空间内声明所有内容.
// Lib1.hpp
namespace Lib1 {
class Class1;
void func1();
// ...
}
Run Code Online (Sandbox Code Playgroud)
现在假设我的库引用了另一个库,Lib2这是一个由其他人提供的C库.
/* Lib2.h */
#ifdef __cplusplus
extern "C" {
#endif …Run Code Online (Sandbox Code Playgroud) 我正在为此提交GCC错误,但我宁愿仔细检查一下.
考虑以下程序:
#include <utility>
template<typename T, typename A>
void F(A&& a) { T(std::forward<A>(a)); } // Note: () syntax.
int main() { int i; F<int&>(i); }
Run Code Online (Sandbox Code Playgroud)
和:
#include <utility>
template<typename T, typename A>
void F(A&& a) { T{std::forward<A>(a)}; } // Note: {} syntax.
int main() { int i; F<int&>(i); }
Run Code Online (Sandbox Code Playgroud)
最新的Clang和MSVC编译器都接受这两个程序.GCC 5及以后接受第一个程序,但拒绝第二个程序,声称invalid cast of an rvalue expression of type 'int' to type 'int&'.
这是GCC的错误吗?还是这的确之间的差异T{},并T()在上述背景下(因此臭虫锵和MSVC)?
编辑:
问题可以缩小到以下简单的摘录:
int i; (int&){i};
Run Code Online (Sandbox Code Playgroud)
和
int i; (int&)(i);
Run Code Online (Sandbox Code Playgroud) 我有一个makefile,它使用$(info)函数调用向用户显示一些信息.但是,makefile还包括通过更新自动生成的依赖项文件gcc -M.每当需要重新创建这样的依赖项时,GNU Make会再次重新编译所有内容,从而复制使用$(info)和类似调用生成的输出.
有没有办法确定GNU Make是否在makefile中执行第一个或第二个这样的传递,以避免重复$(info)行?