So, a couple things:

Firstly:

I think it's pretty sad that this idiom of manually dealing with memory layout 
is used all over the place, and has basically no abstraction. In addition to 
having to coordinate carefully between allocation and access, as it stands, 
it's almost impossible to tell from the header what the layout of the object 
actually is -- for example, in Decl.h, there's no hint that ImportDecl has a 
SourceLocation array appended to it. This is somewhat unfortunate.

I understand that it's done this way for speed and memory efficiency, but I 
can't help but think there *must* be a better way to accomplish it than to 
splatter manual object size arithmetic and reinterpret casts so widely over the 
codebase.

It'd be great if the GCC zero-length-array extension could be used, or if C++ 
had adopted C11's flexible array members. That would help in the perhaps 75% of 
cases where it's just a single optional trailing object, or array of trailing 
objects of the same type.

That makes the allocation size arithmetic easier -- `offsetof(Type, 
arrayfield[num_elements])`. It makes the access easier (just reference the 
field). And it makes the alignment simply handled by the compiler. I believe 
GCC's extension is supported by GCC, Clang, and VC++. I guess there's a desire 
to not use extensions like that even if they are supported by the compilers we 
care about?

And besides being not standard C++, that also wouldn't work for the ~25% of 
cases which have multiple kinds of appended objects, that come one after 
another. As an alternative to the GCC zero-length-array option, I had thought 
of perhaps making a template base class that handles these sorts of layouts, 
somehow, but hadn't really thought it through terribly far how it might work. 
(Or if it'd be too complicated to even be worth it.)

Secondly:

There are more cases where the suggestion doesn't work than just forward 
declarations. "this + 1" or "X + 1" is only used some of the time, there's many 
other ways that code accesses appended objects.

E.g. DeclTemplate.h DependentFunctionTemplateSpecializationInfo has:

  FunctionTemplateDecl * const *getTemplates() const {
    return 
reinterpret_cast<FunctionTemplateDecl*const*>(&getTemplateArgs()[NumArgs]);
  }

Or then there's DeclRefExpr

  return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
      llvm::alignAddr(&getInternalFoundDecl() + 1,
                      llvm::alignOf<ASTTemplateKWAndArgsInfo>()));

which re-aligns, and thus doesn't require that getInternalFoundDecl() is 
aligned properly for the ASTTemplateKWAndArgsInfo object -- but the base 
DeclRefExpr itself really ought to be aligned enough for 
ASTTemplateKWAndArgsInfo, or else the layout of the object would change 
depending on its address!

Annnnnnnnnnnnnnnnnyways:

I had originally started to put these asserts in the constructors, but that 
seemed far from the accesses and was hidden off in a random cpp file, and 
sometimes there are multiple of them, spread around. So I tried the accesses, 
but sometimes those were spread around multiple places too. So eventually I 
just settled on the class definition, because it's always right there and 
there's one of it. :)

I can make the requested change, in the subset of cases where it works, and 
will certainly do so if still requested. But I'm not really sure it's worth it, 
because it removes what is often the only documentation of Weirdness going on, 
at the class definition site.

And, I think the Right Thing is to address the deeper problem of what really 
seems to me like borderline unreadable code -- somehow. If that can be done, it 
will naturally allow alignment asserts to be removed at the same time as the 
casts and sizeof arithmetic, because it'd be unnecessary if the compiler or 
some common library code was ensuring that allocation and sizing and offsets 
and alignment are all done consistently and correctly.


http://reviews.llvm.org/D10272




_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to