只需找到这个有趣的:-)如果指定0f
,该值将被解释为八进制整数文字.因此,不允许f
(十进制15
).00f
并且.f
也不起作用.似乎工作的唯一方法是0.f
和.0f
.还有其他方法吗?不过,我无法弄清楚为什么0.f
有效.被0
解释为八进制前缀?C++肯定很复杂,甚至是非常基本的语法〜> _ <〜
关于以下代码片段的问题
char *p = malloc(10);
Run Code Online (Sandbox Code Playgroud)
当我编译它gcc的任何-std=
,这并编译好.
但是使用g ++,-std=
这会产生错误:
w.c:4:21: error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]
char *p = malloc(10);
Run Code Online (Sandbox Code Playgroud)
为什么行为不同?我认为用C编译的所有行都应该用C++编译器编译.这有什么标准要求吗?
让我们看看以下代码:
int i = 10;
char c = reinterpret_cast<char&>(i);
Run Code Online (Sandbox Code Playgroud)
如果可以使用reinterpret_cast将"指向T1的指针"类型的表达式显式转换为"指向T2的指针"类型,则可以将类型T1的glvalue表达式强制转换为"对T2的引用".结果引用与源glvalue相同的对象,但具有指定的类型.
所以reinterpret_cast<char&>(i)
具有指定char
类型的左值引用该int
对象i
.
要进行初始化c
,我们需要值,因此应用左值到右值的转换[conv.lval] /3.4:
glvalue指示的对象中包含的值是prvalue结果.
L2R转换的结果是i
对象中包含的值.只要值i
在char
([expr]/4表示否则这是UB)可表示的范围内,变量c
应初始化为具有相同的值.
从实现POV开始,在little-endian平台上,通过读取i
对象地址处的字节可以轻松实现.但是,在big-endian平台上,编译器必须添加一个偏移量来获取最低有效字节.或者,将整个int
对象读入寄存器并屏蔽第一个字节,这对两个端点都是可接受的方法.
如果您认为编译器可以轻松处理上面的代码以生成符合C++ 17标准所要求的代码,那么可以考虑将指针int
指向指向i
的指针char
.这样的转换不会改变指针值,即它仍然指向int
对象i
,这意味着将间接运算符应用于具有以下L2R转换的指针应该如上所述,即int
如果是,则获取对象的值按char
类型表示.
在以下代码中
int i = 10;
f(reinterpret_cast<char*>(&i)); // void f(char*)
Run Code Online (Sandbox Code Playgroud)
如果编译器i
不知道函数f
将对其参数做什么,那么编译器是否应该调整某个偏移的地址?并且编译器也不知道将传递给函数的内容f
.上面的代码和函数f
在不同的翻译单元中.
例如,如果f …
=>在C++中不可重载.我一直想知道这是否只是一个纯粹的巧合,或者是否有一个特定的原因,这两个字符的序列不能重载.比较运算符<=>的出现让我相信前者.
我认为它是重载的主要候选者,因为它看起来像一个箭头,这在函数式编程语法和数学中非常常见.当然 - >已经存在但是有另一个箭头可能有助于消除两者之间的歧义.我也看不出它是如何破坏向后兼容性的.
我注意到C ++ 17中的许多新功能来自C17。两种标准之间有关系吗?C函数和它们的C ++等效项之间是否有实际区别?
ISO:IEC 9899 标准化了 C 标准库函数的原型并描述了它们的行为。它指定标识符、返回类型和参数及其匹配的某个 C 标准函数的类型。
但是为什么它没有指定定义 - (具体功能实际上如何工作的核心)?
为什么 C 标准库函数 X 在 Linux 上的 gcc 编译器套件(GNU C 库)、macOS 上的 clang 套件和 Windows 上的 Microsoft Visual C++ 的核心系统动态库之间的实际源代码会有所不同?为什么它依赖于实现、操作系统和相关的编译器设计?
编辑:我知道这个问题乍一看对你们大多数人来说似乎很糟糕,但它绝对有权得到回答,因为我还不知道原因。
我不建议 ISO 对定义进行标准化,因为该问题是基于意见而结束的——不要误会我的意思。我只是问为什么事情会这样,并想从您的知识和经验中学习。
正如标题所说:C++ 标准是否有任何保证可以确保&&
(或and
) 运算符的左侧始终首先计算?老实说,我在C++17 Standard 中搜索不到,我不知道我最想找哪个部分。
我想做这样的事情:
std::unordered_map<std::size_t, std::weak_ptr<T>> objects;
bool f (std::size_t const id) {
bool result = false;
if (not objects.at(id).expired()) {
auto const& object = objects.at(id).lock();
/* Here left side of `and` most be evaluated first */
result = object->parent->remove(id) and
objects.erase(id) == 1;
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
并且要确保代码没有问题。
我有一张桌子,我们称之为A
。我想从该表中删除 ID 为 1 和 2 的行。为此,我创建了一个表变量@B
,其中包含值 1 和 2,但该列我将命名为PK
。
现在我这样做:
DELETE FROM A
WHERE ID IN (
SELECT ID
FROM @B
)
Run Code Online (Sandbox Code Playgroud)
请注意我的(故意的)编程错误。在子选择中,我使用了错误的列名。意外地,它与表 A 中使用的名称相同。
这应该会导致“无效的列名”错误,对吧?但事实并非如此。它执行。不仅如此,表 A 中的所有数据都被删除。就好像不再有谓词一样。
我创建了一个完整的演示脚本:
-- What happened to my data???
IF OBJECT_ID('tempdb..#JustATable') IS NOT NULL
DROP TABLE #JustATable
CREATE TABLE #JustATable (
PK INT NOT NULL PRIMARY KEY IDENTITY(1, 1),
ID INT NOT NULL,
NOTE VARCHAR(100) NOT NULL
)
INSERT INTO #JustATable (ID, NOTE)
SELECT database_id, DB_NAME(database_id)
FROM …
Run Code Online (Sandbox Code Playgroud) void foo (std::deque<Class>& dq)
{
auto it = dq.begin();
--it; // <--- asserts in VC++
...
}
Run Code Online (Sandbox Code Playgroud)
上面的代码是一个过于简化的版本,但类似的情况也发生在我的代码中。它在 Ubuntu/Linux 中运行良好,但在 Visual Studio 中断言和中止程序。
表达式:无法在开始之前递减双端队列迭代器
有关程序如何导致断言失败的信息,请参阅 VC++ ...
即使我们没有寻找或取消引用迭代器的值,为什么它会将其视为运行时错误?
language-lawyer ×10
c++ ×8
c ×3
byte ×1
c++17 ×1
c17 ×1
deque ×1
endianness ×1
function ×1
iso ×1
iterator ×1
libc ×1
literals ×1
sql ×1
sql-server ×1
syntax ×1
t-sql ×1
visual-c++ ×1