拿这个代码:
int issuecode(int i)
{
return 2 * i;
}
int main(int argc, char **argv)
{
return issuecode(argc);
}
Run Code Online (Sandbox Code Playgroud)
我理解它的方式,如果编译为C程序,它将具有未定义的行为.我的理由基于这些标准报价:
C99,7.26(或C11,7.31)
为方便起见,以下名称分组在各个标题下.无论程序包含哪些标题,下面描述的所有外部名称都是保留的.
C99,7.26.2(或C11,7.31.2)
以
is或开头的函数名称to和小写字母可以添加到<ctype.h>标题中的声明中.
C99,7.1.3(或C11,7.1.3)
每个标头声明或定义其关联子条款中列出的所有标识符,并可选地声明或定义其关联的未来库方向子条款和标识符中列出的标识符,这些标识符始终保留用于任何用途或用作文件范围标识符.
[...]
- 所有以下子条款中包含外部链接的标识符(包括未来的库方向)始终保留用作具有外部链接的标识符.
[...]如果程序在保留它的上下文中声明或定义标识符(除了7.1.4允许的标识符),或者将保留标识符定义为宏名称,则行为是未定义的.
基于以上所述,我认为函数名issuecode实际上是保留用于<ctype.h>,因此该程序在技术上具有UB.
问题0(健全性检查):我的标准读数是否正确,程序的行为在技术上是不确定的?
问题1:如果编译为C++代码,程序是否会有UB?
我相信答案是"不",如下面的引言所示,我会说C的"未来图书馆方向"不是C++标准库的一部分,但我不太确定.
C++ 11,21.7
表74,75,76,77,78,和79描述头
<cctype>,<cwctype>,<cstring>,<cwchar>,<cstdlib>(字符转换),和<cuchar>分别.这些标头的内容应是相同的标准C库头
<ctype.h>,<wctype.h>,<string.h>,<wchar.h>,和<stdlib.h>分别以及C的Unicode TR头,具有以下修改:
"以下修改"均未提及附加的保留标识符.表74是与isdigit和等函数名称的分类列表isalnum. …
我试图将成员函数指针传递给c风格的函数(因为它是C中的lib)
它想要的指针定义为:
void (*)(int, const char*)
Run Code Online (Sandbox Code Playgroud)
所以我试图传递的功能是:
void Application::onError(int error, const char *description)
Run Code Online (Sandbox Code Playgroud)
我试图通过这段代码传递:
setCallback(bind(&Game::onError, this, placeholders::_1, placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
cannot convert ‘std::_Bind_helper<false, void (Application::*)(Application*, int,
const char*), Application* const, const std::_Placeholder<1>&, const
std::_Placeholder<2>&>::type {aka std::_Bind<std::_Mem_fn<void (Application::*)
(Application*, int, const char*)>(Application*, std::_Placeholder<1>,
std::_Placeholder<2>)>}’ to ‘GLFWerrorfun {aka void (*)(int, const char*)}’ for
argument ‘1’ to ‘void (* glfwSetErrorCallback(GLFWerrorfun))(int, const char*)’
glfwSetErrorCallback(bind(&Application::onError, this, placeholders::_1, placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
有没有办法成功将成员函数作为绑定函数传递给c风格的函数?
假设我有一个函数,就像这样:
void mysort(int *arr, std::size_t size)
{
std::sort(&arr[0], &arr[size]);
}
int main()
{
int a[] = { 42, 314 };
mysort(a, 2);
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:(mysort更具体地说,&arr[size])代码是否定义了行为?
我知道如果被替换为完全有效arr + size; 指针算法允许正常指向过去.不过,我的问题是关于具体的使用&和[].
Per C++ 11 5.2.1/1,arr[size]相当于*(arr + size).
引用5.3.1/1,一元的规则*:
一元运算
*符执行间接:它所应用的表达式应该是指向对象类型的指针,或指向函数类型的指针,结果是引用表达式指向的对象或函数 的左值.如果表达式的类型是"指向T",则结果的类型为"T."[ 注意:可以取消引用指向不完整类型(cvvoid除外)的指针.由此获得的左值可以以有限的方式使用(例如,初始化参考); 这个左值不能转换为prvalue,见4.1.- 尾注 ]
最后,5.3.1/3给出了以下规则&:
一元运算
& …
我刚刚开始使用C++ 11线程,我一直在努力(可能是愚蠢的)错误.这是我的示例程序:
#include <iostream>
#include <thread>
#include <future>
using namespace std;
class A {
public:
A() {
cout << "A constructor\n";
}
void foo() {
cout << "I'm foo() and I greet you.\n";
}
static void foo2() {
cout << "I'm foo2() and I am static!\n";
}
void operator()() {
cout << "I'm the operator(). Hi there!\n";
}
};
void hello1() {
cout << "Hello from outside class A\n";
}
int main() {
A obj;
thread t1(hello1); // it works …Run Code Online (Sandbox Code Playgroud) 我在Web上找到了一个示例cmake文件,并将其放在/doc我的项目的子目录中,该文件myproject.doxgen也位于该文件中,其中包含Doxygen配置.
我已经测试了运行doxygen.exe myproject.doxygen产生的有效输出.我只需要将其构建到CMake过程中.所以/doc/CMakeLists.txt是:
find_package(Doxygen)
option(BUILD_DOCUMENTATION "Create and install the HTML based API
documentation (requires Doxygen)" ${DOXYGEN_FOUND})
if(BUILD_DOCUMENTATION)
if(NOT DOXYGEN_FOUND)
message(FATAL_ERROR "Doxygen is needed to build the documentation.")
endif()
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/../doc/myproject.doxygen)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/doxyfile)
configure_file(${doxyfile_in} ${doxyfile} @ONLY)
message("Doxygen build started.")
add_custom_target(doc
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile_in}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/doc
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
# install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html DESTINATION share/doc)
endif()
Run Code Online (Sandbox Code Playgroud)
它不适用于我,它只复制原始配置文件,/build/my/project/doc/并且不做任何其他操作.
我想要的是在我的构建期间生成doxygen文档; 理想情况下,仅在构建Release配置时.
假设我在C++中有以下代码:
#include <memory>
#include <iostream>
struct Some {
Some(int _a) : a(_a) {}
int a;
};
int main() {
Some some(5);
std::unique_ptr<Some> p1 = std::make_unique<Some>(some);
std::unique_ptr<Some> p2 = std::make_unique<Some>(some);
std::cout << p1->a << " " << p2->a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,使用唯一指针来保证资源不被共享.但在这种情况下,两个p1和p2指向同一个实例some.
请揭开这种情况.
我用GCC,Clang,ICC和VS测试了以下代码:
void f() {}
void g(void (&&)()) { }
int main() {
g(f);
}
Run Code Online (Sandbox Code Playgroud)
正如我们所看到的,g采用右值引用但是f是左值,并且通常,右值引用不能绑定到左值.这正是ICC抱怨的:
error: an rvalue reference cannot be bound to an lvalue
Run Code Online (Sandbox Code Playgroud)
VS也会出错,但出于另一个原因:
error C2664: 'void h(void (__cdecl &&)(void))' : cannot convert parameter 1 from 'void (__cdecl *)(void)' to 'void (__cdecl &&)(void)'
Run Code Online (Sandbox Code Playgroud)
这告诉我VS立即执行函数到指针的转换,而不是直接绑定引用f.值得一提的是,如果我替换g(f)为g(&f)那么四个编译器会产生同样的错误.
最后,GCC和Clang接受了代码,我相信它们是正确的.我的推理基于8.5.3/5
对类型"cv1 T1"的引用由类型"cv2 T2"的表达式初始化为
- 如果参考是左值参考[...]
- 否则,[...] 参考应为右值参考.
- 如果初始化表达式是 [...] 函数左值 [...]
然后 …
我一直在尝试实现类似于static_assertC++ 11标准中定义的方法.主要问题是C++编译器如何将传递给的文本消息static_assert写成const char*?我可以让编译器写一个像这样的消息A_is_not_POD.这就是我所拥有的:
#define MY_STATIC_ASSERT(condition, name) \
typedef char name[(condition) ? 1 : -1];
Run Code Online (Sandbox Code Playgroud)
但是让编译器编写类似"Error: A is not POD."Any建议的东西会很好吗?
我正在尝试在Codeblocks中调试C++项目,但它并没有在断点处停止.我读了其他答案,到目前为止尝试了以下内容:
Build Options > Compiler Settings)Produce debugging symbols已选中,strip all symbols未选中.Settings > Compiler > Toolchain Executables)中的调试器设置为GDB/CDB Debugger:DefaultSettings > Debugger > GDB/CDB Debugger:Default)中的可执行路径是C:\MinGW\bin\gdb.exe.它仍然没有停在断点处,调试器日志提到没有找到调试符号我在这里缺少什么?
我正在观看Jason Turner的一个视频,我看到你可以在函数范围内定义一个类型,并通过函数返回类型推导使其在该范围之外可用.
auto f()
{
struct MyStruct
{
int n;
};
return MyStruct{};
}
int main()
{
auto a = f().n;
return a;
}
Run Code Online (Sandbox Code Playgroud)
为什么允许这样做?C++ 14标准中是否有允许这样的段落?
当试图获得typeid的MyStruct与铛编译探险我在装配输出类型显示为看到f()::MyStruct,所以有一个范围,但不知何故,我可以访问MyStruct该范围之外.这是某种ADL的事吗?