From mboxrd@z Thu Jan 1 00:00:00 1970 MIME-Version: 1.0 In-Reply-To: References: <8edba5d726ee6a032d8521c7de33f499@felloff.net> Date: Tue, 5 Jan 2016 11:01:36 -0800 Message-ID: From: "Devon H. O'Dell" To: Fans of the OS Plan 9 from Bell Labs <9fans@9fans.net> Content-Type: text/plain; charset=UTF-8 Subject: Re: [9fans] subtracting pointers on amd64 6c Topicbox-Message-UUID: 7e42ff8a-ead9-11e9-9d60-3106f5b1d025 2016-01-05 2:28 GMT-08:00 Charles Forsyth : > since 6c is more commonly used now, and there's more interest or need, it's > probably best just to introduce > the difference type and change the result type. it's the same thing with > usize. i get that probably nobody cares about c standards here, but it might be useful to mention what c99 and c11 say about this issue, since the behavior is well-defined for every other c implementation (and minus having a ptrdiff_t type, there's actually nothing wrong with the current behavior). the latest particulars in c11 defining ptrdiff_t and pointer addition and subtraction are at http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf page 93. ptrdiff_t was introduced in c99. the type specifies behavior of pointer subtraction where the pointers point to elements within an array object. the size of this type is implementation defined. when the pointers are not both pointer to members of the same array object (or one past it), or when the difference of the subtraction falls out of the range of the implementation's ptrdiff_t type, the behavior is undefined. i think practically, this means that the behavior is undefined if the pointers belong to two separate memory allocations since variable-length arrays are array objects *and* are dynamically allocated -- so this isn't making a strong statement that the pointers have to be inside something declared `T foo[N]`, but it is making a statement that they have to be inside or one past a contiguous memory region of the same type (and could alias). so given any of the examples in this thread, if you typedef'ed ptrdiff_t to long, then the compiler technically isn't actually doing anything wrong. whether it is doing something useful is a different question. for practical purposes, if the compiler learned about a ptrdiff_t type (or whatever you feel like calling it), and that type was 64 bits, it would be enough to represent the difference between any two physical addresses that amd64 could represent. for instance, although the range of subtraction is theoretically -2^64+1 to 2^64-1, amd64 can only address 48 bits of memory (currently) despite using 64 bits to represent addresses. as long as virtual addresses in the system aren't exabytes apart, this shouldn't result in undefined behavior in practice.