根据[lex.phases] 1.2中的这句话
除了在原始字符串文字中恢复的拼接外,如果拼接导致字符序列与通用字符名称的语法匹配,则行为未定义.
下面的代码段有未定义的行为(live-example):
#include <iostream>
// According to [lex.phases]1.2 this has undefined behavior
const char* p = "\\
u0041";
int main()
{
std::cout << p << '\n';
}
Run Code Online (Sandbox Code Playgroud)
未定义行为的原因是什么?
在[dcl.ambig.res]/2中,我们发现以下内容:
void foo(signed char a) {
sizeof(int(a)); // expression
sizeof(int(unsigned(a))); // type-id (ill-formed)
}
Run Code Online (Sandbox Code Playgroud)
为什么是int(a)表达式和int(unsigned(a))类型ID?
乍一看,我会说两者都是表达.
编译器使用模板版本来计算t = max(a, b)和max(t, c).支持此标准的任何引用都是受欢迎的.
#include <iostream>
template <typename T>
inline T const& max (T const& a, T const& b)
{
std::cout << "template" << '\n';
return a < b ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c);
}
inline int const& max (int const& a, int const& b)
{
std::cout << "non-template" << '\n';
return a <b …Run Code Online (Sandbox Code Playgroud) C++ 14中的[class.copy]/12:
如果不是用户提供的,则类X的复制/移动构造函数是微不足道的,其参数类型列表等效于隐式声明的参数类型列表,如果
否则复制/移动构造函数是非平凡的.
我可以看到上面的句子在N4606中被删除了,但我在C++标准核心语言活动问题修订版96中找不到任何东西来证明它从C++中删除14.
甲标准布局类用于在C++ 14 [类]/7定义如下(重点是矿):
一个标准的布局类是一类:
我关注的是bullet(7.5):如何在最派生的类中没有非静态数据成员,同时有一个基类具有非静态数据成员?
换句话说,不是基类的非静态数据成员,也是最派生类的非静态数据成员?
[dcl.link]/4中的第五个例子说明如下:
extern "C" {
static void f4(); // the name of the function f4 has internal linkage (not C language linkage)
// and the function’s type has C language linkage.
}
Run Code Online (Sandbox Code Playgroud)
为什么是这样?为什么函数的名称f4具有内部链接,而不是C语言链接?
PS:我是从语言律师的角度问这个.也就是说,如何从标准中的规范段落中得出上述评论声明?
我在VS2017中调试了以下代码(请注意下面的断点):
接下来,您会发现上面提到的断点的反汇编:
如上图所示,编译器为该指令生成的机器代码call dword ptr [fp]是FF 55 F8,其中FF是调用指令的操作码,55是ModeR/M字节的值,F8是值为-8的8位位移,将在下面解释。
现在,如果您查看下面的“表2-2:具有ModeR / M的32位寻址形式”字节,该字节是从英特尔的“ 64 IA-32体系结构软件开发人员手册”第2A卷获得的,上面提到的55号对应于一个有效地址[EBP]+disp8。也就是说,CALL汇编器中的指令将跳转到其地址是从寄存器EBP中的地址加上上述值-8的8位位移获得的指令。这个地址是正确的。它对应于一条JMP指令的地址,该地址最终将代码传递给函数f。
因此,一切看起来都很好。但是我缺少一个重要的点:我应该已经ModeR/M使用英特尔手册中的CALL指令参考以及上面的表2.2 获取了该字节。但是我仍然不知道该怎么做。任何提示都会受到高度赞赏,因为我已经为此工作了几天,而我对此一无所知。
例如,clang不编译此代码,因为struct A下面的默认默认构造函数A() = default;不被视为用户提供.
struct A{ A() = default; };
const A a;
Run Code Online (Sandbox Code Playgroud)
但如果你看[dcl.fct.def.general]/1,你会看到:
function-body:
ctor-initializer opt compound-statement
function-try-block
= default ;
= delete ;
也就是说,= default;是函数体的默认构造函数A::A(),这是相同的话说,定义A() = default;上述相当于A(){}为{}是身体的默认构造函数.
顺便说一句,g++汇编上面的片段,但我知道g++在这方面还有其他问题,根据Jonathan Wakely的评论.
我之所以这样问是因为,尽管表11的标题是简单类型说明符及它们指定的类型,但语法生成简单类型说明符并未提及这种类型的组合,简单类型说明符.那么unsigned int一个简单类型说明符呢?
编辑:我不认为上述问题的答案是正确的.如果这是真的,那么就不能说声明.void* operator new(std::size_t);是[dcl.dcl]/1中定义的声明,正如在我的系统中所定义的那样.为了证明这一说法,即是一个声明,我几乎可以肯定,我们所需要的事实,即是一个简单的类型说明符.size_ttypedefunsigned intvoid* operator new(std::size_t);unsigned int 我错了.如果我们使用[dcl.type.simple]/1中给出的type-name定义,那么说这.我认为我第一次是对的,除了错误的例子.也就是说,我认为void* operator new(std::size_t);是一个声明是没有问题的unsigned int 必须是一个简单类型说明符,否则就不能说这void f(unsigned int);是一个声明.
.
C++ 11标准中的哪个子句允许我在下面A的return语句中消除它A::operator-()?换句话说,如果我return A{-a.i, -a.j};通过return {-a.i, -a.j};代码替换表达式编译并正确执行.如果可能的话,我想知道如何使用标准?
#include <iostream>
struct A {
int i;
int j;
A(int n, int m) : i(n), j(m) {}
};
A operator-(A a) { return A{-a.i, -a.j}; }
int main()
{
A a(1, 2);
A b = -a;
std::cout << b.i << " " << b.j << '\n';
}
Run Code Online (Sandbox Code Playgroud) 这个/ENTRY (MASM) 文件在其备注部分说:
评论
/ENTRY 选项将入口点函数指定为 .exe 文件或 DLL 的起始地址。
该函数必须定义为使用 __stdcall 调用约定。
这似乎并不完全正确,因为下面的代码在 VS2017 中没有问题。
.586
.MODEL flat, C
.stack 4096
.CODE
main PROC
mov eax, -1
main ENDP
END
Run Code Online (Sandbox Code Playgroud)
其中main定义为链接器选项 /ENTRY 中的代码入口点。请注意,main它不使用stdcall调用约定。
突出显示的句子是否仅指用 C 或 C++ 编写的代码?
仅用于文档,我在用于运行代码的链接器命令行下方提供:
/OUT:"C:\Users\xxxx\Documents\Visual Studio 2017\Projects\Assemblies\Debug\A_test.exe" /MANIFEST
/NXCOMPAT /PDB:"C:\Users\xxxx\Documents\Visual Studio 2017\Projects\Assemblies\Debug\A_test.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib"
"shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG:FASTLINK
/MACHINE:X86 /ENTRY:"main" /INCREMENTAL /PGD:"C:\Users\xxxx\Documents\Visual Studio
2017\Projects\Assemblies\Debug\A_test.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Debug\A_test.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO …Run Code Online (Sandbox Code Playgroud)