相关疑难解决方法(0)

在C++中,C风格的演员可以调用转换函数然后抛弃constness吗?

GCC和Clang都拒绝接受以下代码中的C风格演员.

http://coliru.stacked-crooked.com/a/c6fb8797d9d96a27

struct S {
    typedef const int* P;
    operator P() { return nullptr; }
};
int main() {
    int* p1 = const_cast<int*>(static_cast<const int*>(S{}));
    int* p2 = (int*)(S{});
}
Run Code Online (Sandbox Code Playgroud)
main.cpp: In function 'int main()':
main.cpp:7:25: error: invalid cast from type 'S' to type 'int*'
     int* p2 = (int*)(S{});
main.cpp:7:15: error: cannot cast from type 'S' to pointer type 'int *'
    int* p2 = (int*)(S{});
              ^~~~~~~~~~~

但是,根据标准,C风格的演员表可以执行a static_cast后跟a 执行的转换const_cast.这段代码是否格式良好?如果没有,为什么不呢?

c++ language-lawyer

27
推荐指数
1
解决办法
530
查看次数

为什么(int&)0格式不正确?

根据[expr.cast]/4,C风格的强制转换按顺序尝试以下强制转换:

  1. const_cast
  2. static_cast
  3. static_cast 其次是 const_cast
  4. reinterpret_cast
  5. reinterpret_cast 其次是 const_cast

以下演员表格很好:

const_cast<int&>(static_cast<const int&>(0))
Run Code Online (Sandbox Code Playgroud)

然而,GCC和Clang都拒绝演员(int&)0.为什么?

c++ casting const-cast static-cast language-lawyer

24
推荐指数
1
解决办法
434
查看次数

C++规范是否说明在static -cast/const_cast链中如何选择类型以用于C风格的转换?

这个问题涉及我在C++规范中注意到的事情,当我试图回答这个问题时,有关C风格的转换和类型转换的有趣问题.

C++规范在§5.4中讨论了C风格的演员表.它表示强制转换符号将按此顺序尝试以下强制转换,直到找到一个有效:

  • const_cast
  • static_cast
  • static_cast 其次是 const_cast
  • reinterpret_cast
  • reinterpret_cast接着是const_cast.

虽然我有意味着什么,使用一个伟大的直观的想法static_cast,然后一const_cast(例如,在转换const Derived*Base*通过一个去const_cast<Base*>(static_cast<const Base*>(expr)),我没有看到任何规范写法怎么说,具体而言,使用的类型)在static_cast/ const_cast系列中将被推断.在简单指针的情况下,它并不那么难,但正如链接问题中所见,如果const在一个地方引入额外内容并在另一个地方删除附加内容,则施法可能会成功.

是否有任何规则来管理编译器如何确定在铸造链中使用哪些类型?如果是这样,他们在哪里?如果不是,这是语言中的缺陷,还是有足够的隐式规则来唯一确定要尝试的所有可能的强制转换?

c++ casting language-lawyer

14
推荐指数
1
解决办法
188
查看次数

r值参考铸造和临时物化

下面代码的输出产生:

void doit(const T1 &, const T2 &) [T1 = unsigned long, T2 = int]
t1 == t2
t1 == (T1)t2
t1 != (T1&)t2
t1 == (T1&&)t2
Run Code Online (Sandbox Code Playgroud)

我知道这个t1 == t2案子只是一个不可或缺的促销活动.

第二种情况t1 == (T1)t2是相同的,只是明确的.

第三种情况t1 == (T1&)t2必须是reinterpret_cast某种形式......但是,进一步的解释会有所帮助.

第四种情况t1 == (T1&&)t2是我坚持的.我在问题的标题中加入了"临时实现"这个术语,因为这是我能得到某种答案的最接近的.

有人可以查看这四个案例吗?

码:

#include <iostream>    

template <typename T1, typename T2>
void doit(const T1& t1, const T2& t2) {
  std::cout << __PRETTY_FUNCTION__ << '\n';

  if (t1 == t2) {
    std::cout << "t1 == …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer c++11

11
推荐指数
1
解决办法
502
查看次数

使用(float&)int工作类型punning,(float const&)int转换为(float)int而不是?

VS2019,发布,x86.

template <int i> float get() const {
    int f = _mm_extract_ps(fmm, i);
    return (float const&)f;
}
Run Code Online (Sandbox Code Playgroud)

使用return (float&)f;编译器时使用

extractps m32, ...
movss xmm0, m32
Run Code Online (Sandbox Code Playgroud)

.正确的结果

使用return (float const&)f;编译器时使用

extractps eax, ...
movd xmm0, eax
Run Code Online (Sandbox Code Playgroud)

.错误的结果

T&和T const&首先是T然后是const的主要思想.Const只是程序员的某种协议.你知道你可以解决它.但汇编代码中没有任何const,但是类型为float IS.我认为对于float和float const而言它必须是汇编中的浮点表示(cpu寄存器).我们可以使用中间int reg32,但最终解释必须是float.

而此时它看起来像回归,因为这之前工作正常.并且在这种情况下使用float也绝对是奇怪的,因为我们不应该考虑浮动const和安全性而是浮动的临时变量并且确实值得怀疑.

微软回答:

嗨Truthfinder,感谢自成一体的复制品.碰巧,这种行为实际上是正确的.正如我的同事@Xiang Fan [MSFT]在内部电子邮件中所述:

由[a c-style cast]执行的转换尝试以下序列:(4.1) - const_cast(7.6.1.11),(4.2) - static_cast(7.6.1.9),(4.3) - static_cast后跟const_cast ,(4.4) - reinterpret_cast(7.6.1.10)或(4.5) - reinterpret_cast后跟const_cast,

如果转换可以用上面列出的多种方式解释,则使用列表中首先出现的解释.

所以在你的情况下,(const float&)被转换为static_cast,其效果是"初始化表达式被隐式转换为类型为"cv1 T1"的prvalue.应用临时实现转换并将引用绑定到结果".

但在另一种情况下,(float&)被转换为reinterpret_cast,因为static_cast无效,这与reinterpret_cast(&operand)相同.

您正在观察的实际"错误"是一个强制转换:"将浮点型值"1.0"转换为等效的int-typed值"1"",而另一个强制转换说"将1.0的位表示形式转换为一个浮点数,然后将这些位解释为int".

出于这个原因,我们建议不要使用c风格的演员表.

谢谢!

MS论坛链接:https://developercommunity.visualstudio.com/content/problem/411552/extract-ps-intrinsics-bug.html

有任何想法吗?

PS我真正想要的是什么:

float val …
Run Code Online (Sandbox Code Playgroud)

c++ assembly sse intrinsics visual-c++

6
推荐指数
2
解决办法
299
查看次数