• <legend id='eiAPq'><style id='eiAPq'><dir id='eiAPq'><q id='eiAPq'></q></dir></style></legend>
      • <bdo id='eiAPq'></bdo><ul id='eiAPq'></ul>

      <tfoot id='eiAPq'></tfoot>

      <small id='eiAPq'></small><noframes id='eiAPq'>

        <i id='eiAPq'><tr id='eiAPq'><dt id='eiAPq'><q id='eiAPq'><span id='eiAPq'><b id='eiAPq'><form id='eiAPq'><ins id='eiAPq'></ins><ul id='eiAPq'></ul><sub id='eiAPq'></sub></form><legend id='eiAPq'></legend><bdo id='eiAPq'><pre id='eiAPq'><center id='eiAPq'></center></pre></bdo></b><th id='eiAPq'></th></span></q></dt></tr></i><div id='eiAPq'><tfoot id='eiAPq'></tfoot><dl id='eiAPq'><fieldset id='eiAPq'></fieldset></dl></div>

        索引结构是否合法?

        时间:2023-07-01

              <legend id='DWIpi'><style id='DWIpi'><dir id='DWIpi'><q id='DWIpi'></q></dir></style></legend>

                  <tbody id='DWIpi'></tbody>
              • <tfoot id='DWIpi'></tfoot>
                • <bdo id='DWIpi'></bdo><ul id='DWIpi'></ul>

                  <small id='DWIpi'></small><noframes id='DWIpi'>

                  <i id='DWIpi'><tr id='DWIpi'><dt id='DWIpi'><q id='DWIpi'><span id='DWIpi'><b id='DWIpi'><form id='DWIpi'><ins id='DWIpi'></ins><ul id='DWIpi'></ul><sub id='DWIpi'></sub></form><legend id='DWIpi'></legend><bdo id='DWIpi'><pre id='DWIpi'><center id='DWIpi'></center></pre></bdo></b><th id='DWIpi'></th></span></q></dt></tr></i><div id='DWIpi'><tfoot id='DWIpi'></tfoot><dl id='DWIpi'><fieldset id='DWIpi'></fieldset></dl></div>

                • 本文介绍了索引结构是否合法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

                  问题描述

                  不管代码有多糟糕",并且假设对齐等在编译器/平台上不是问题,这是未定义或损坏的行为吗?

                  Regardless of how 'bad' the code is, and assuming that alignment etc are not an issue on the compiler/platform, is this undefined or broken behavior?

                  如果我有这样的结构:-

                  If I have a struct like this :-

                  struct data
                  {
                      int a, b, c;
                  };
                  
                  struct data thing;
                  

                  abc 作为 (&thing.a)[0](&thing.a)[1](&thing.a)[2]?

                  Is it legal to access a, b and c as (&thing.a)[0], (&thing.a)[1], and (&thing.a)[2]?

                  在每种情况下,在我尝试过的每个编译器和平台上,我尝试过的每个设置都有效".我只是担心编译器可能没有意识到 bthing[1] 是同一个东西,并且存储到 'b' 可能会被放在一个寄存器中[1] 从内存中读取错误的值(例如).在每种情况下,我都尝试过它做了正确的事情.(我当然意识到这并不能证明什么)

                  In every case, on every compiler and platform I tried it on, with every setting I tried it 'worked'. I'm just worried that the compiler might not realize that b and thing[1] are the same thing and stores to 'b' might be put in a register and thing[1] reads the wrong value from memory (for example). In every case I tried it did the right thing though. (I realize of course that doesn't prove much)

                  这不是我的代码;这是我必须使用的代码,我对这是代码还是损坏代码很感兴趣,因为不同的代码会影响我对其进行大量更改的优先级:)

                  This is not my code; it's code I have to work with, I'm interested in whether this is bad code or broken code as the different affects my priorities for changing it a great deal :)

                  标记 C 和 C++ .我主要对 C++ 感兴趣,但如果 C 不同,我也会感兴趣,只是为了兴趣.

                  Tagged C and C++ . I'm mostly interested in C++ but also C if it is different, just for interest.

                  推荐答案

                  这是非法的1.这是 C++ 中的未定义行为.

                  It is illegal 1. That's an Undefined behavior in C++.

                  您以数组方式获取成员,但这是 C++ 标准所说的(重点是我的):

                  You are taking the members in an array fashion, but here is what the C++ standard says (emphasis mine):

                  [dcl.array/1]::strong> ...数组类型的对象包含一个连续分配的非空 N 集合T 类型的子对象...

                  [dcl.array/1]: ...An object of array type contains a contiguously allocated non-empty set of N subobjects of type T...

                  但是,对于成员来说,没有这样的连续要求:

                  But, for members, there's no such contiguous requirement:

                  [class.mem/17]::strong> ...;实现对齐要求 可能会导致两个相邻的成员不要紧随其后分配...

                  [class.mem/17]: ...;Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other...

                  虽然上面的两个引号应该足以暗示为什么像您那样对 struct 进行索引不是 C++ 标准定义的行为,但让我们举一个例子:看看表达式 (&thing.a)[2] - 关于下标运算符:

                  While the above two quotes should be enough to hint why indexing into a struct as you did isn't a defined behavior by the C++ standard, let's pick one example: look at the expression (&thing.a)[2] - Regarding the subscript operator:

                  [expr.post//expr.sub/1]:后缀表达式后跟方括号中的表达式是后缀表达式.表达式之一应是类型的泛左值T 数组"或指向 T 的指针"类型的纯右值,另一个应是无作用域枚举或整数类型的纯右值.结果是T"型.类型T"应是完全定义的对象类型. 66表达式 E1[E2]((E1)+(E2))

                  [expr.post//expr.sub/1]: A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall be a glvalue of type "array of T" or a prvalue of type "pointer to T" and the other shall be a prvalue of unscoped enumeration or integral type. The result is of type "T". The type "T" shall be a completely-defined object type.66 The expression E1[E2] is identical (by definition) to ((E1)+(E2))

                  深入研究上面引用的粗体文本:关于将整数类型添加到指针类型(注意这里的重点)..

                  Digging into the bold text of the above quote: regarding adding an integral type to a pointer type (note the emphasis here)..

                  [expr.add/4]::strong> 当一个整数类型的表达式被添加到一个或从一个指针,结果具有指针操作数的类型.如果表达式P指向数组对象x的元素x[i]对于 n 个元素,表达式 P + JJ + P(其中 J 有值 j) 指向(可能是假设的)元素 x[i + j]如果 0 ≤ i + j ≤ n;否则,行为未定义....

                  [expr.add/4]: When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i + j] if 0 ≤ i + j ≤ n; otherwise, the behavior is undefined. ...

                  注意if 子句的array 要求;else 上面引用中的否则.表达式 (&thing.a)[2] 显然不符合 if 子句的条件;因此,未定义行为.

                  Note the array requirement for the if clause; else the otherwise in the above quote. The expression (&thing.a)[2] obviously doesn't qualify for the if clause; Hence, Undefined Behavior.

                  附带说明:虽然我在各种编译器上对代码及其变体进行了广泛的试验,但它们在这里没有引入任何填充,(它有效);从维护的角度来看,代码是极其脆弱的.在执行此操作之前,您仍然应该断言实现是连续分配成员的.并留在界内:-).但它仍然是未定义的行为......

                  On a side note: Though I have extensively experimented the code and its variations on various compilers and they don't introduce any padding here, (it works); from a maintenance view, the code is extremely fragile. you should still assert that the implementation allocated the members contiguously before doing this. And stay in-bounds :-). But its still Undefined behavior....

                  其他答案提供了一些可行的解决方法(具有定义的行为).

                  Some viable workarounds (with defined behavior) have been provided by other answers.

                  正如评论中正确指出的那样,[basic.lval/8],在我之前的编辑中不适用.感谢@2501 和@M.M.

                  As rightly pointed out in the comments, [basic.lval/8], which was in my previous edit doesn't apply. Thanks @2501 and @M.M.

                  1:请参阅@Barry 对此问题的回答,了解唯一一种可以通过此部分访问结构的 thing.a 成员的法律案例.

                  1: See @Barry's answer to this question for the only one legal case where you can access thing.a member of the struct via this parttern.

                  这篇关于索引结构是否合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

                  <tfoot id='x6FdJ'></tfoot>

                            <bdo id='x6FdJ'></bdo><ul id='x6FdJ'></ul>
                            <i id='x6FdJ'><tr id='x6FdJ'><dt id='x6FdJ'><q id='x6FdJ'><span id='x6FdJ'><b id='x6FdJ'><form id='x6FdJ'><ins id='x6FdJ'></ins><ul id='x6FdJ'></ul><sub id='x6FdJ'></sub></form><legend id='x6FdJ'></legend><bdo id='x6FdJ'><pre id='x6FdJ'><center id='x6FdJ'></center></pre></bdo></b><th id='x6FdJ'></th></span></q></dt></tr></i><div id='x6FdJ'><tfoot id='x6FdJ'></tfoot><dl id='x6FdJ'><fieldset id='x6FdJ'></fieldset></dl></div>

                            <small id='x6FdJ'></small><noframes id='x6FdJ'>

                            <legend id='x6FdJ'><style id='x6FdJ'><dir id='x6FdJ'><q id='x6FdJ'></q></dir></style></legend>
                              <tbody id='x6FdJ'></tbody>