Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] tailored_alloc/delete: make connection_table a CRTP base class #230

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

Quuxplusone
Copy link
Contributor

Supersedes #229.

The way to fix -Woverloaded-virtual is to make the overload set non-virtual, and make the virtual function list non-overloaded. Also, make the virtual functions non-public, to ensure that nobody accidentally calls them directly and/or non-virtually. (This patch is a specific application of the Non-Virtual Interface Idiom, of which I am a huge fan. I didn't apply it generally to the whole codebase or even the whole class, only targeted to fix this specific problem; but I certainly wouldn't object if it started being used more widely.)

I don't think the overloading of the name relative_matrix is mechanically important, but I was too lazy to go change all the call-sites to call relative_matrixc or relative_matrixh as appropriate.

@zenorogue
Copy link
Owner

I seem to get an error in gcc 11.1.0:

locations.cpp:183:47: error: ‘degree’ is not a constant expression
  183 |   size_t num_bytes = offsetof(T, c.move_table[degree]) + degree;

GCC isn't happy with a simple
    size_t num_bytes = offsetof(T, c.move_table[degree]) + degree;
so we have to keep the multiplication for now.
It's now 8 bytes bigger than before, but more type-safe
and doesn't require offsetof anymore.
We don't want `c1->spin(d)` to compile, but we do want `c1->c().spin(d)`
to compile. Make the CRTP inheritance private and make `->c()` the
magic incantation to poke through that privateness.
@Quuxplusone Quuxplusone changed the title Fixes to tailored_alloc/delete, and fix all -Woverloaded-virtual warnings. tailored_alloc/delete: make connection_table a CRTP base class Jul 12, 2021
@Quuxplusone
Copy link
Contributor Author

Ah, the simple offsetof is foiled by GCC, okay. I've got a better idea anyway. This PR is now based on top of #233, so please look at that one first (and hopefully merge it as non-controversial). Then, there are 4 commits here that aren't in #233. The ultimate effect is to make c1->c().spin(d) mean exactly the same thing as c1->c.spin(d) used to mean; but without any offsetof calculations.

Ideally, @jruderman would confirm or deny that the static analyzer is happy with this approach. If this makes the static analyzer confused, then it's probably not an improvement.

Comment on lines -348 to -350
/** \brief connection table */
connection_table<heptagon> c;
// DO NOT add any fields after connection_table! (see tailored_alloc)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's the benefit of the CRTP approach. We no longer have a named c data member that must-be-the-last-in-the-class. Instead, we have a base class trailing_connection_table, which provides a member function c() that returns basically (connection_table<heptagon>*)(this + 1).

@jruderman
Copy link
Contributor

With these changes, I get a crash on startup in hr::geometry_information::generate_floorshapes:

(16ee53e; Apple Clang on Mac)

@Quuxplusone
Copy link
Contributor Author

With these changes, I get a crash on startup in hr::geometry_information::generate_floorshapes:

Oh, crap. I don't get the crash myself (Clang trunk, OSX), but I agree, I see where it comes from.

heptagon modelh;
cell model;
model.master = &modelh;
modelh.c7 = &model;
model.type = modelh.type = S7;

and then later:

vector<cell> models(n);
vector<heptagon> modelh(n);

My changes make it so that when you allocate just a heptagon or a cell through normal means, e.g. on the stack, you get a "degree-zero" object, not a "degree-120" object. So that's a problem.

I'm thinking about adding a helper factory function, like

std::unique_ptr<cell, tailored_deleter<cell>>
make_tailored(int degree) {
  size_t num_bytes = T::tailored_alloc_size(degree);
  T* result = ::new (::operator new(num_bytes)) T();
  result->type = degree;
  result->c().fullclear();
  return std::unique_ptr<cell, tailored_deleter<cell>>(result);
  }

and then replacing all those cell instances with std::unique_ptr<cell, tailored_deleter<cell>> instead. That's going to make this patch even more invasive than it already is. But maybe it'll come out the other side looking easier and safer...

@Quuxplusone Quuxplusone changed the title tailored_alloc/delete: make connection_table a CRTP base class [WIP] tailored_alloc/delete: make connection_table a CRTP base class Jul 13, 2021
@zenorogue
Copy link
Owner

I do not think there is much point to hide the "spin" and "mirror" functions (it was originally h->c.spin and h->c.mirror because I decided it was easier to do it that way than to define "spin" and "mirror" shortcuts, but with the CRTP approach I think h->spin and h->mirror are nicer).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants