小编san*_*orn的帖子

c++11 严格别名规则是否允许通过 char *、char(&)[N]、甚至 std::array<char, N>& 和 -fstrict-aliasing -Wstrict-aliasing=2 访问 uint64_t?

根据有关C++11/14严格别名规则的stackoverflow答案:

如果程序尝试通过以下类型之一以外的泛左值访问对象的存储值,则行为未定义:

  • 对象的动态类型,

  • 对象动态类型的 cv 限定版本,

  • 与对象的动态类型类似的类型(如 4.4 中定义),
  • 与对象的动态类型相对应的有符号或无符号类型,
  • 与对象动态类型的 cv 限定版本相对应的有符号或无符号类型,
  • 聚合或联合类型,其元素或非静态数据成员中包括上述类型之一(递归地包括子聚合或包含的联合的元素或非静态数据成员),
  • 是对象动态类型的(可能是 cv 限定的)基类类型的类型,
  • acharunsigned char类型。

我们可以使用以下方式访问其他类型的存储吗

(1)char *

(2)char(&)[N]

(3)std::array<char, N> &

不依赖于未定义的行为

constexpr uint64_t lil_endian = 0x65'6e'64'69'61'6e; 
    // a.k.a. Clockwise-Rotated Endian which allocates like
    // char[8] = { n,a,i,d,n,e,\0,\0 }

const auto& arr =   // std::array<char,8> &
    reinterpret_cast<const std::array<char,8> &> (lil_endian);

const auto& carr =  // char(&)[8]>
    reinterpret_cast<const char(&)[8]>           (lil_endian);

const auto* …
Run Code Online (Sandbox Code Playgroud)

c++ strict-aliasing language-lawyer c++11

5
推荐指数
1
解决办法
380
查看次数

为什么c ++标准不保证对象数组与其第一个元素之间的指针可互换性?

根据这个

http://eel.is/c++draft/basic.compound#4

如果出现以下情况,则两个对象a和b是指针可互换的:

  • 它们是同一个对象,或者
  • 一个是union对象,另一个是该对象的非静态数据成员([class.union]),或
  • 一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则该对象的第一个基类子对象([class.mem]) ), 要么
  • 存在对象c,使得a和c是指针可互换的,并且c和b是指针可互换的.

如果两个对象是指针可互换的,则它们具有相同的地址,并且可以通过reinterpret_cast从指向另一个的指针获得指向一个对象的指针.[  注意:数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址. - 结束说明]

为什么c ++标准不保证对象数组与其第一个元素之间的指针可互换性,而保证类及其第一个成员?

为什么这是未定义的行为?

char carr[8];
char& ch0 = carr[0];
auto& carr2 = reinterpret_cat<char (&) [8]>(ch0); // Is this considered undefined behavior?

// Because ch0 (char&) and carr2 (char(&)[8]) are not "pointer-interconvertible".
// So they can not use reinterpret_cast "definedly".
// Array and its first element are not "pointer-interconvertible"
// eventhough they share the same address.
Run Code Online (Sandbox Code Playgroud)

虽然这是标准本身的一个例子.

http://www.eel.is/c++draft/basic.types#2

#define N sizeof(T)
char buf[N];
T obj;                          // obj initialized …
Run Code Online (Sandbox Code Playgroud)

c++ undefined-behavior reinterpret-cast c++11 c++17

5
推荐指数
0
解决办法
155
查看次数

如何约束参数类型只允许std :: initializer_list <size_t>或std :: array <size_t,N>?

我想只有一个模板功能.所以我想出来......

template<typename Iteratable, size_t N,
         typename = 
            std::enable_if_t<
                std::is_same_v<Iteratable, const std::initializer_list<size_t> > ||
                std::is_same_v<Iteratable, const std::array<size_t, N > >
            > 
>
std::ostream& operator << (std::ostream& os, Iteratable& in) {
    std::copy(std::begin(in), std::end(in), std::ostream_iterator<size_t>(os, " ") ); 
    return os;
}
Run Code Online (Sandbox Code Playgroud)

似乎因为Nin std::array<size_t, N>,专业化失败了.

有没有怎么不写这个用例的2函数?

c++ templates template-meta-programming

5
推荐指数
1
解决办法
126
查看次数

为什么将`const char [N]`和`const char*`传递给view :: c_str()会产生不同的二进制文件,而string_view会产生相同的结果吗?

随着std::string_view,与两者range::for_each产生精确组装const char[N]const char *传递给std::string_viewctor

换句话说,这段代码

auto str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(std::string_view{str}, std::putchar);
Run Code Online (Sandbox Code Playgroud)

auto& str = "the quick brown fox is jumping on a lazy dog\nthe quick brown fox is jumping on a lazy dog\n";
ranges::for_each(std::string_view{str}, std::putchar);
Run Code Online (Sandbox Code Playgroud)

两者都低于汇编:

main:                                   # @main
        pushq   %rbx
        movq    $-90, %rbx
.LBB0_1:                                # =>This Inner Loop …
Run Code Online (Sandbox Code Playgroud)

c++ optimization range-v3 string-view

5
推荐指数
1
解决办法
148
查看次数

为什么 clang 认为 gcc 的子范围不满足 gcc 的 __ranges_begin 函数概念要求?

clang 失败的代码(而 gcc 似乎很好)

    int arr[] { 111, 222, 333};
    ranges::subrange(
        ranges::begin(arr),ranges::end(arr) );
Run Code Online (Sandbox Code Playgroud)

看起来clang声称gcc的子范围没有开始功能?!

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:953:35: note: and 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized> &' does not satisfy '__member_begin'

      requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>

                                  ^

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:937:33: note: because '__detail::__decay_copy(__t.begin())' would be invalid: no member named 'begin' in 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized>'

          { __detail::__decay_copy(__t.begin()) } -> input_or_output_iterator;

                                       ^

/opt/compiler-explorer/gcc-snapshot/lib/gcc/x86_64-linux-gnu/11.0.0/../../../../include/c++/11.0.0/bits/iterator_concepts.h:953:59: note: and 'std::ranges::subrange<int *, int *, std::ranges::subrange_kind::sized> &' does not satisfy '__adl_begin'

      requires is_array_v<_Tp> || __member_begin<_Tp&> || __adl_begin<_Tp&>
Run Code Online (Sandbox Code Playgroud)

[直播]


gcc …

c++ clang c++-concepts range-v3 c++20

5
推荐指数
0
解决办法
133
查看次数

我们称之为像C :: C(const C &&)这样的构造函数?除了禁止从const移动之外,还有它的用途吗?

我可以声明三个构造函数

  • 复制构造函数 C::C(const C&)
  • 移动构造函数 C::C(C&&)
  • C::C(const C&&)

在一个没有歧义的课堂上.

我们称之为构造函数的是C::C(const C&&)什么?它有什么昵称吗?

我可以提出=delete明确禁止用户在不知不觉中尝试移动const并限制自动复制后备效果.这会提醒用户他们正在做什么.

还有其他用途吗?

c++ constructor c++11

4
推荐指数
1
解决办法
104
查看次数

当相同的约束必须推导出不同类型时,为什么将概念放入类型说明符失败类型推导?

我们有:

template <typename ...T> concept bool Numerics = ( std::is_arithmetic_v<T> && ... ) ;
template <typename T>    concept bool Numeric  =   std::is_arithmetic_v<T>;
Run Code Online (Sandbox Code Playgroud)

然后我们让编译器推导出所有数字:

template <typename T, typename U, typename V, typename W> requires Numerics<T,U,V,W>
auto foo(T arg1, U arg2, V arg3, W arg4) {
    return 0.0 + arg1 + arg2 + arg3 + arg4;
}

std::cout << foo (1,2.0,3.0f,4.0l) << "\n";
Run Code Online (Sandbox Code Playgroud)

编译器推导出预期的所有参数类型:

auto foo<int, double, float, long double>(int, double, float, long double):
Run Code Online (Sandbox Code Playgroud)

当我们尝试将约束分配到类型说明符中以编写更短的版本时:

auto foo2(Numeric arg1, Numeric arg2, Numeric arg3, …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++-concepts type-deduction

4
推荐指数
1
解决办法
93
查看次数

将迭代器解引用到临时范围时出现非指针操作数错误

运用

auto empty_line = [](auto& str){ return str.size() == 0; };
Run Code Online (Sandbox Code Playgroud)

我们做得到:

auto line_range_with_first_non_empty = 
                ranges::view::drop_while(ranges::getlines(std::cin),empty_line);
auto input1 = std::stoi(*line_range_with_first_non_empty.begin());
Run Code Online (Sandbox Code Playgroud)

我们也可以这样做:

auto line_range2 = ranges::getlines(std::cin);
auto iter2 = ranges::find_if_not(line_range2,empty_line);
auto input2 = std::stoi(*iter2);
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我尝试将以上版本缩短为:

auto iter3 = ranges::find_if_not(ranges::getlines(std::cin),empty_line);
// auto input3 = std::stoi(*iter3);
Run Code Online (Sandbox Code Playgroud)

我收到一个错误:

<source>:22:29: error: indirection requires pointer operand ('ranges::v3::dangling<ranges::v3::_basic_iterator_::basic_iterator<ranges::v3::getlines_range::cursor> >' invalid)
    auto input3 = std::stoi(*iter3);
                            ^~~~~~
Run Code Online (Sandbox Code Playgroud)

我认为这是因为无限范围,但我错了.

auto sin = std::istringstream{"\n\n\nmy line\n"};
auto iter4 = ranges::find_if_not(ranges::getlines(sin),empty_line);
// Error when deref.
// auto input4 = std::stoi(*iter4);
Run Code Online (Sandbox Code Playgroud)

这会产生相同的错误.

<source>:27:29: error: …
Run Code Online (Sandbox Code Playgroud)

c++ lazy-evaluation c++11 range-v3

4
推荐指数
1
解决办法
322
查看次数

P0960,是否有某种机制可以检测c ++ 20中带有()的新聚合init的范围是否缩小?

使用P0960 “允许从带括号的值列表中初始化聚合”时,也可以使用()s 进行聚合init 。

但是,此初始化允许缩小,而{}s不允许。

#include <vector>
#include <climits>

struct Foo
{
  int x, y;
};

int main()
{
  // auto p = new Foo{INT_MAX, UINT_MAX}; // still won't compile
  auto q = new Foo(INT_MAX, UINT_MAX);    // c++20 allows narrowing aggregates init

  std::vector<Foo> v;
  // v.emplace_back(Foo{INT_MAX, UINT_MAX}); // still won't compile
  v.emplace_back(INT_MAX, UINT_MAX);         // c++20 allows narrowing aggregates init
                                             // in furtherly perfect forwardings
}
Run Code Online (Sandbox Code Playgroud)

是否可以使用带括号的C ++ 20聚合初始化来检测变窄的转换?

c++ c++-standard-library narrowing c++20

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

如何仅针对源代码的特定部分打开 -mavx2?

-march我可以强制编译器在代码的某些特定部分的设置之外编译一些内部函数吗?

当然,其余的还是在-march设定范围内。

是否可以-mavx2仅启用源代码的特定部分?

或者是我必须单独编译部分的唯一方法-mavx2

c++ gcc clang intrinsics avx2

4
推荐指数
1
解决办法
996
查看次数