标签: language-lawyer

为什么"使用命名空间X;" 在类/结构级别内是不允许的?

class C {
  using namespace std;  // error
};
namespace N {
  using namespace std; // ok
}
int main () {
  using namespace std; // ok
}
Run Code Online (Sandbox Code Playgroud)

编辑:想知道背后的动机.

c++ namespaces using language-lawyer

77
推荐指数
4
解决办法
5万
查看次数

我可以使用 NULL 代替 0 的值吗?

我可以使用NULL指针代替 的值0吗?

或者这样做有什么问题吗?


比如,例如:

int i = NULL;
Run Code Online (Sandbox Code Playgroud)

作为替代:

int i = 0;
Run Code Online (Sandbox Code Playgroud)

作为实验,我编译了以下代码:

#include <stdio.h>

int main(void)
{
    int i = NULL;
    printf("%d",i);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

0
Run Code Online (Sandbox Code Playgroud)

事实上,它给了我这个警告,这本身是完全正确的:

warning: initialization makes integer from pointer without a cast [-Wint-conversion] 
Run Code Online (Sandbox Code Playgroud)

但结果仍然是等价的。


  • 我是否会因此而进入“未定义行为”?
  • 可以这样使用NULL吗?
  • NULL在算术表达式中用作数值有什么问题吗?
  • 对于这种情况,C++ 中的结果和行为是什么?

我已阅读的答案是什么NULL之间的区别,“\ 0”和0大约之间的区别是什么NULL\0以及0是的,但我没有从那里简洁的信息,如果是很允许的,也是正确的使用NULL作为在赋值和其他算术运算中使用的值。

c c++ null pointers language-lawyer

77
推荐指数
7
解决办法
7224
查看次数

通过C++标准的下标:legal来获取一个过去的数组元素的地址?

我已经看过它多次断言现在C++标准不允许使用以下代码:

int array[5];
int *array_begin = &array[0];
int *array_end = &array[5];
Run Code Online (Sandbox Code Playgroud)

&array[5]在这种情况下是合法的C++代码吗?

如果可能的话,我想要一个参考标准的答案.

知道它是否符合C标准也很有趣.如果它不是标准的C++,为什么决定做出从不同的治疗呢array + 5还是&array[4] + 1

c c++ standards language-lawyer

75
推荐指数
6
解决办法
6741
查看次数

是否允许编译器优化本地volatile变量?

是否允许编译器对此进行优化(根据C++ 17标准):

int fn() {
    volatile int x = 0;
    return x;
}
Run Code Online (Sandbox Code Playgroud)

这个?

int fn() {
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果是,为什么?如果没有,为什么不呢?


这里有一些关于这个主题的思考:当前编译器编译fn()为放在堆栈上的局部变量,然后返回它.例如,在x86-64上,gcc创建了这个:

mov    DWORD PTR [rsp-0x4],0x0 // this is x
mov    eax,DWORD PTR [rsp-0x4] // eax is the return register
ret    
Run Code Online (Sandbox Code Playgroud)

现在,据我所知,标准并没有说应该将一个局部volatile变量放在堆栈上.所以,这个版本同样好:

mov    edx,0x0 // this is x
mov    eax,edx // eax is the return
ret    
Run Code Online (Sandbox Code Playgroud)

这里,edx商店x.但是现在,为什么要停在这里?由于edxeax均为零,我们可以只说:

xor    eax,eax // eax is the return, and x as well
ret    
Run Code Online (Sandbox Code Playgroud)

我们转变 …

c++ volatile language-lawyer c++17

75
推荐指数
5
解决办法
5748
查看次数

C 或 C++ 是否保证 array &lt; array + SIZE?

假设你有一个数组:

int array[SIZE];
Run Code Online (Sandbox Code Playgroud)

或者

int *array = new(int[SIZE]);
Run Code Online (Sandbox Code Playgroud)

C 或 C++ 是否保证array < array + SIZE,如果是,在哪里?

我知道无论语言规范如何,许多操作系统通过为内核保留虚拟地址空间的顶部来保证此属性。我的问题是语言是否也保证这一点,而不仅仅是绝大多数实现。

举个例子,假设一个操作系统内核处于低内存中,有时会向用户进程提供虚拟内存的最高页面,以响应mmap对匿名内存的请求。如果malloc::operator new[]直接要求mmap分配一个巨大的数组,并且数组的末尾紧靠虚拟地址空间的顶部,从而array + SIZE环绕为零,这是否等于该语言的不合规实现?

澄清

请注意,问题不是问 about array+(SIZE-1),它是数组最后一个元素的地址。那一个保证大于array。问题是关于超过数组末尾的指针,或者p+1何时p是指向非数组对象的指针(所选答案指向的标准部分明确表示以相同方式处理)。

计算器要我解释,为什么这个问题是不一样的这一个。另一个问题询问如何实现指针的总排序。另一个问题本质上归结为一个库如何实现std::less它甚至可以用于指向不同分配对象的指针,标准说只能比较相等,而不是大于和小于。

相比之下,我的问题是关于数组末尾的一个是否总是保证大于数组。我的问题的答案是或否实际上并没有改变你将如何实施std::less,所以另一个问题似乎并不相关。如果与数组末尾的比较是非法的,那么std::less在这种情况下可能只是表现出未定义的行为。(此外,通常标准库是由与编译器相同的人实现的,因此可以自由利用特定编译器的属性。)

c c++ language-lawyer

74
推荐指数
5
解决办法
6562
查看次数

虚空的大小是多少?

这个陈述会产生什么?

void *p = malloc(sizeof(void));
Run Code Online (Sandbox Code Playgroud)

编辑:问题的扩展.

如果sizeof(void)在GCC编译器中产生1,那么分配1个字节的内存并且指针p指向该字节并且p ++将递增到0x2346?假设p是0x2345.我说的是p而不是*p.

c c++ sizeof language-lawyer

73
推荐指数
6
解决办法
6万
查看次数

在c ++ 0x中删除nullptr仍然是安全的吗?

c++03它是很清楚,删除一个空指针没有任何效果.实际上,它明确指出§5.3.5/2:

在任一替代方案中,如果delete的操作数的值是空指针,则操作无效.

然而,在目前的草案对于c++0x这句话似乎缺少.在草稿的其余部分,我只能找到句子,说明如果delete-expression的操作数不是空指针常量会发生什么.是否删除仍然定义的空指针c++0x,如果是,在哪里?

笔记:

有大量的间接证据表明它仍然有明确的定义.

首先,有两句话§5.3.5/2说明

在第一个替代(删除对象)中,delete的操作数的值可以是空指针值,...

在第二个替代(删除数组)中,delete的操作数的值可以是空指针值或...

这些说操作数被允许为空,但是它们自己实际上并没有定义如果是的话会发生什么.

其次,改变意义delete 0是一个重大的突破性变化,标准委员会不太可能做出这种特殊的改变.此外,没有提到这是c++0x草案兼容性附件(附件C)的重大变化.但是,附件C是一个信息性部分,因此对标准没有任何解释.

另一方面,删除空指针要求无效的事实意味着额外的运行时检查.在很多代码中,操作数永远不能为空,因此这个运行时检查与零开销原则相冲突.也许委员会刚刚决定改变行为,使标准c ++更符合语言的既定设计目标.

c++ null language-lawyer delete-operator

73
推荐指数
2
解决办法
4万
查看次数

静态成员函数中的`this`类型?

在C++ 5.1.1/3 [expr.prim.general]中,它说:

类型和值类别[of this]在静态成员函数中定义.

这是什么意思?它有什么关系?

注意:

this 不应出现在静态成员函数的声明中

c++ language-lawyer c++11

73
推荐指数
1
解决办法
1855
查看次数

在POSIX系统上,argc可以为零吗?

鉴于主程序的标准定义:

int main(int argc, char *argv[]) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

argcPOSIX系统在哪些情况下可以为零?

c posix program-entry-point language-lawyer

73
推荐指数
4
解决办法
4269
查看次数

保证执行memcpy(0,0,0)是否安全?

我不太熟悉C标准,所以请耐心等待.

我想知道,按标准保证memcpy(0,0,0)是否安全.

我能找到的唯一限制是,如果内存区域重叠,那么行为是未定义的......

但我们可以认为这里的内存区域重叠吗?

c memcpy null-pointer language-lawyer

72
推荐指数
2
解决办法
2万
查看次数