标签: language-lawyer

读取未初始化的变量

读取未初始化的变量会导致未定义的行为,例如

#include <iostream>

int main()
{
    int a;
    std::cout << a << std::endl; // undefined behavior
}
Run Code Online (Sandbox Code Playgroud)

有人可以对这个事实给出正式的解释吗?

c++ language-lawyer

0
推荐指数
1
解决办法
976
查看次数

函数调用中的 Python 推导式 (PEP 448)

(这都是Python 3.5.2上的)

在PEP 448的底部,我看到:

函数调用中不带括号的推导式(例如 )f(x for x in it)已经有效。

这很有趣。如果我定义以下函数:

def f(a, b, c):
    return a + b + c
Run Code Online (Sandbox Code Playgroud)

那么这个措辞让我这么认为f(thing for thing in [1, 2, 3]) == 6。但实际上,我得到:

>>> f(thing for thing in [1, 2, 3])
TypeError: f() missing 2 required positional arguments: 'b' and 'c'
Run Code Online (Sandbox Code Playgroud)

即整个生成器表达式作为 传递a

那么PEP 448中的这句话是什么意思呢?只是您可以传递生成器表达式作为参数吗?

python language-lawyer python-3.x

0
推荐指数
1
解决办法
115
查看次数

转换后的常量表达式写法

[expr.const] p9定义转换后的常量表达式为:

\n\n
\n

A\xc2\xa0 conversionconstant expression \xc2\xa0of type\xc2\xa0 T\xc2\xa0是一个表达式,隐式转换为类型\xc2\xa0T,其中转换后的表达式是常量表达式,隐式转换序列仅包含 [。 ..]

\n
\n\n

在以下示例中:

\n\n
const int a = 42;\nint b[a];\n
Run Code Online (Sandbox Code Playgroud)\n\n

该标准没有指定应用于的转换是否a是表达式求值的一部分(事实上,它们被认为是完整表达式的一部分,即初始化声明符),并且如果不指定这一点,它实际上意味着任何类型的泛左值表达式int都是转换后的常量表达式,因为转换不是结果纯右值评估的一部分(应用转换,产生纯右值,然后评估该纯右值)。是我错了,还是措辞有缺陷?

\n

c++ language-lawyer

0
推荐指数
1
解决办法
117
查看次数

.Net 中的复合赋值

我想知道 .Net 中是否曾经或仍然存在过这种情况。

使用 exp += val 而不是 exp = exp + val。由于 exp 可以任意复杂,这可能会导致大量不必要的工作。这迫使 JIT 评估 exp 的两个副本,但很多时候这是不需要的。第一个语句的优化效果比第二个语句好得多,因为 JIT 可以避免对 exp 求值两次。

这是来自 codeproject 中的一篇古老文章。

cpp中还有另外一个:

但是,复合赋值表达式并不等同于扩展版本,因为复合赋值表达式仅对 expression1 求值一次,而扩展版本对 expression1 求值两次:在加法运算和赋值运算中。

.net c# optimization language-lawyer compound-assignment

0
推荐指数
1
解决办法
1704
查看次数

Can the qsort comparison function always return a non-zero value?

An ascending sort callback function for qsort and bsearch on an array of int could look like this:

int ascending(const void *o1, const void *o2) {
    int a = *(const int *)o1;
    int b = *(const int *)o2;
    return a < b ? -1 : 1;
}
Run Code Online (Sandbox Code Playgroud)

Yet this function seems to violate the constraint on the compar function as specified in the C Standard:

7.22.5.2 The qsort function

Synopsis

#include <stdlib.h>
void qsort(void *base, size_t nmemb, size_t size,
           int …
Run Code Online (Sandbox Code Playgroud)

c sorting qsort language-lawyer

0
推荐指数
1
解决办法
109
查看次数

为什么 std::iterator_traits 中的几乎所有类型别名都没有默认值?

在不借助 boost.iterator 等库的帮助下创建 C++20 之前的新迭代器时,有必要指定类型别名difference_typevalue_typepointer和。 根据cppreference 对于 C++20,只需要指定和referenceiterator_categorydifference_typevalue_type这很棒!但是为什么这 3 个别名有默认值呢?

有两件事我不明白(其中一件事在我看来像是一个疏忽):

  1. value_type为什么和没有默认值difference_type?使用类似的东西std::remove_reference_t<reference>作为默认值难道没有意义吗value_type?作为随机访问迭代器的默认设置difference_type,使用采用两个迭代器的运算符的结果类型可以说是有意义的-
  2. C++20 添加了contiguous_iterator_tag. 就像与input_iterator_tagvsforward_iterator_tag一样,我不明白编译器如何正确区分连续迭代器和随机访问迭代器,我想这就是它显然从不选择的原因contiguous_iterator_tag。这是故意的吗?将输入迭代器错误分类为前向迭代器似乎也有些危险,那么为什么不要求程序员自己指定此别名呢?
  3. 在一个有点不相关的说明上,我不确定即使iterator_category程序员已经明确声明了另一个类别,但默默地生成一个值是否是一个好主意,并且为iterator_category它生成一个与看起来完全不同的值concept也很奇怪。考虑这个不切实际的例子:
#include <iostream>
#include <iterator>

// With the == operator, this is an input iterator, but nothing else.
struct WeirdIterator {
    // Not an output iterator because …
Run Code Online (Sandbox Code Playgroud)

c++ iterator language-lawyer c++20

0
推荐指数
1
解决办法
330
查看次数

如果一元运算符的优先级接近最高,那么为什么 # 和 ## 运算符的计算顺序未指定?

简单的问题:如果一元运算符的优先级接近最高,那么为什么#and##运算符的计算顺序是未指定的?与 C 和 C++ 相关。

C11(6.10.3.2 # 运算符):

# 和 ## 运算符的计算顺序未指定。

C++,N4713(19.3.2 # 运算符):

# 和 ## 运算符的计算顺序未指定。

c c++ language-lawyer c++17 c17

0
推荐指数
1
解决办法
74
查看次数

为什么在父类之前调用​​子类的析构函数?

在C++中,当对象的析构函数被调用时,它首先调用子类的析构函数,然后是父类的析构函数,这与构造过程相反。但为什么?这似乎是一个简单的问题,但我还没有在互联网上找到令人满意的答案。有人可以解释以这种顺序进行破坏的必要性吗?

c++ language-lawyer

0
推荐指数
1
解决办法
115
查看次数

不支持的标准功能是否会影响一致性?

上下文:C 编译器在实现一致的同时故意不支持某些功能。可以吗?

\n

一些例子。下面的所有编译器都是一致的实现(__STDC__定义为1)。然而:

\n
    \n
  • gcc 不支持#pragma STDC FENV_ACCESS并出现问题warning: ignoring \xe2\x80\x98#pragma STDC FENV_ACCESS\xe2\x80\x99 [-Wunknown-pragmas]。然而, fenv.h 是一个标准头文件,#pragma STDC FENV_ACCESS ON标准要求支持 ,因为是on-off-switch :ON中的选择之一。ON OFF DEFAULT

    \n
  • \n
  • msvc 不支持#pragma STDC FP_CONTRACT,而是支持它自己的版本#pragma fp_contract ( { on | off } )。但是,标准版本是#pragma STDC FP_CONTRACT { ON | OFF | DEFAULT }.

    \n
  • \n
  • Cygwin 上的 gcc:sscanf 不处理十六进制浮点输入。libc 是标准的一部分。

    \n
  • \n
\n

问题:是否允许实现故意提供有限的功能(或其自己的此类功能版本),同时仍然符合实现? …

c standards-compliance language-lawyer c11 c17

0
推荐指数
1
解决办法
99
查看次数

指向数组第一个元素之前的一个的指针是 UB。这是什么时候第一次这样定义的?

从 C17 开始,递减指向数组第一个元素的指针是未定义的行为。这个答案引用了C17标准的说法

C17 6.5.6/8

如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则求值不会产生溢出;否则,行为是未定义的。

这是最早定义的标准吗?早期标准中如何定义此类操作?以前合法吗?

c pointer-arithmetic language-lawyer

0
推荐指数
1
解决办法
105
查看次数