This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.

### 2421. Non-specification of handling zero size in `std::align` [ptr.align]

Section: 20.10.5 [ptr.align] Status: New Submitter: Melissa Mears Opened: 2014-08-06 Last modified: 2014-11-03

Priority: 3

View all other issues in [ptr.align].

View all issues with New status.

Discussion:

The specification of `std::align` does not appear to specify what happens when the value of the `size` parameter is 0. (The question of what happens when `alignment` is 0 is mentioned in another Defect Report, 2377; it would change the behavior to be undefined rather than potentially implementation-defined.)

The case of `size` being 0 is interesting because the result is ambiguous. Consider the following code's output:

>     #include <cstdio>
>     #include <memory>

>     int main()
>     {
>       alignas(8) char buffer[8];
>       void *ptr = &buffer[1];
>       std::size_t space = sizeof(buffer) - sizeof(char[1]);

>       void *result = std::align(8, 0, ptr, space);

>       std::printf("%d %td\n", !!result, result ? (static_cast<char*>(result) - buffer) : std::ptrdiff_t(-1));
>     }

There are four straightforward answers as to what the behavior of `std::align` with size 0 should be:

1. The behavior is undefined because the size is invalid.

2. The behavior is implementation-defined. This seems to be the status quo, with current implementations using #3.

3. Act the same as `size == 1`, except that if `size == 1` would fail but would be defined and succeed if space were exactly 1 larger, the result is a pointer to the byte past the end of the `ptr` buffer. That is, the "aligned" version of a 0-byte object can be one past the end of an allocation. Such pointers are, of course, valid when not dereferenced (and a "0-byte object" shouldn't be), but whether that is desired is not specified in the Standard's definition of `std::align`, it appears. The output of the code sample is "`1 8`" in this case.

4. Act the same as `size == 1`; this means that returning "one past the end" is not a possible result. In this case, the code sample's output is "`0 -1`".

The two compilers I could get working with `std::align`, Visual Studio 2013 and Clang 3.4, implement #3. (Change `%td` to `%Id` on Visual Studio 2013 and earlier. 2014 and later will have `%td`.)

Proposed resolution: