Skip to content

GitLab

  • Menu
Projects Groups Snippets
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • VTK-m VTK-m
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 192
    • Issues 192
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 35
    • Merge requests 35
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages & Registries
    • Packages & Registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • VTK
  • VTK-mVTK-m
  • Merge requests
  • !2432

WIP: Make reinterpreting from Variant safer

  • Review changes

  • Download
  • Email patches
  • Plain diff
Closed Kenneth Moreland requested to merge kmorel/vtk-m:variant-safe-punning into master Mar 02, 2021
  • Overview 21
  • Commits 2
  • Pipelines 12
  • Changes 4

I ran into some bizarre behavior with code generated with GCC in optimized mode. I think the problem was that the optimizer was being aggressive in removing computation after reinterpreting pointers.

The C++ standard states that if two pointers or references point to different types of data, they can be considered to point to different memory locations. This often allows the compiler to make much faster code. But it also means that if you pun the data (make the data look like two different things at once) you get undefined behavior.

The commonly accepted solution to the problem is to use std::memcpy to move the data to a pointer of a new type. However, this only works for trivial types, and we need to support non-trivial types.

The solution used here is to allow the data to be punned, but to use std::memmove to alert the compiler that there is a dependence between the two types. The pointers to the memmove are the same, so the compiler should remove any actual work but still record the data dependence. It should also be safe for non-trivial types since you are not actually moving any data.

Technically, this solution still is classified as undefined behavior. However, the only issue you should run into is that changes to the punned data won't reflect each other. This should be addressed in CastAndCall, which does a second memmove after the functor is called in case the object is changed. For the same reason, writing to the value using Get has been disabled to prevent those writes from being out of order.

Edited Mar 22, 2021 by Kenneth Moreland
Assignee
Assign to
Reviewer
Request review from
Time tracking
Source branch: variant-safe-punning