Ad
  • Custom User Avatar

    cppreference on strict aliasing

    Given an object with effective type T1, using an lvalue expression (typically, dereferencing a pointer) of a different type T2 is undefined behavior, unless:

    • T2 and T1 are compatible types.
    • T2 is cvr-qualified version of a type that is compatible with T1.
    • T2 is a signed or unsigned version of a type that is compatible with T1.
    • T2 is an aggregate type or union type type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union).
      cppreference's definition of an aggregate type
      aggregate types: array types and structure types

    Since the type of shape is a struct that contains (directly or recursively) a member of type shape_t, the cast does not violate strict aliasing rules, as struct types are aggregate types.
    (At least according to the definitions on cppreference)

    Furthermore, since the type of shape is a struct that contains (directly or recursively) a member of type shape_t, the alignment of shape is guaranteed to meet the alignment requirements of shape_t.

    Lastly, since the very first member of the type of shape (directly or recursively) is of type shape_t, the offset to that member is guaranteed to be 0.

    Thus, that pointer cast is valid.

  • Custom User Avatar

    my "clever" click goes here

  • Custom User Avatar

    Reraised as issue

  • Default User Avatar

    You can do a hack fix and just do a guard that returns Just 0 if the item is negative

  • Default User Avatar

    BangPatterns was not doing anything in the end, used it before pattern matching and forgot to remove it.

  • Default User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Default User Avatar
  • Default User Avatar

    Disclaimer: one cannot simply understand aliasing, so I'm not entirely sure.
    Given that (const shape_t *)shape is &((const right_triangle_t *)shape)->shape, the underlying type shape_t is the same, so there's no aliasing. The only question is whether the type cast is valid. So there's C11 ("n1570.pdf") 6.7.2.1.15:

    Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

  • Default User Avatar

    Doesn't the code

      return ((const shape_t *)shape)->vtable->get_area(shape);
    

    violate the strict-aliasing rule whenever shape isn't actually a pointer to an object of type shape_t?
    Wouldn't union aliasing be the correct way to do this?
    (I'm quite new to C so this might sound as a dumb question, I'm still trying to understand type aliasing and how to do it right.)

  • Default User Avatar

    This comment is hidden because it contains spoiler information about the solution

  • Default User Avatar

    This solution works for base >= 4.11.0 && < 5 (will probably still be valid for base >= 5, but that doesn't exist as of the time of writing this)

  • Custom User Avatar

    Fixed. Thanks ;-)
    And sorry for late(I haven't seen this issue report before today)

  • Custom User Avatar

    Good point, I guess for no reason.
    I was probably using it for something else in which I needed to specify that a is Fractional, and then I just left it as it was :P

  • Default User Avatar

    C# solution template has the wrong method name (should be UpperCamelCase intead of lowerCamelCase)

  • Default User Avatar
  • Loading more items...