<div dir="auto">Ok. Cool. Im starting to understand now. ThankYou.<div dir="auto"><br></div><div dir="auto">-Pawel</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">wt., 11.05.2021, 11:19 użytkownik David Chisnall via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a>> napisał:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 11/05/2021 07:59, pawel k. via llvm-dev wrote:<br>
> I am very much beginner in opaque pointers but I am also minimalist too <br>
> in a sense entities shouldnt be multiplied but rather divided where <br>
> applicable.<br>
> <br>
> Can someone point me to article(s) describing what problems opaque <br>
> pointers solve that cant be solved with forward declaractions and typed <br>
> pointers etc?<br>
> <br>
> My first gutfeeling was when learning on idea of opaque pointers, theyre <br>
> not much more than void* with all its issues from static analysis, <br>
> compiler design, code readability, code quality, code security <br>
> perspective. Can someone correct a newbie? Very open to change my mind.<br>
<br>
There are a few problems with the current representation and they <br>
largely mirror the old problem with signed vs unsigned integers in the <br>
IR 15 years ago.  In early versions of LLVM, integers were explicitly <br>
signed.  This meant that the IR was cluttered with bitcasts from signed <br>
to unsigned integers, which slowed down analysis and didn't convey any <br>
useful semantics.  Worse, there were a bunch of things conflated, for <br>
example does unsigned imply wrapping?  Some time in the 2.x series (2.0? <br>
  My memory is fuzzy here), LLVM moved to just i{size} types for integer <br>
and moved all of the semantics to the operations.  It's now explicit <br>
whether an operation is signed or unsigned, whether overflow wraps or <br>
has undefined behaviour, and so on.<br>
<br>
Pointers have a similar set of problems.  Pointers carry a type, but <br>
that type doesn't actually carry any semantics.  There are a lot of <br>
things that don't care about the type of the pointer, but they have no <br>
way of specifying this and generally use i8*.  This means that the IR is <br>
full of bitcasts from {something}* to i8* and then back again.<br>
<br>
This is particularly important for code that wants to use non-zero <br>
address spaces, because a lot of code does casts via i8* and forgets to <br>
change this to i8*-in-another-address-space.<br>
<br>
The fact that a pointer is a pointer to some struct type currently <br>
doesn't imply anything about whether the pointed-to data and it's <br>
completely valid to bitcast a pointer to a random type and back again in <br>
an optimisation.  The real type info (where applicable) is carried by <br>
TBAA metadata, dereferencability info by attributes, and so on.<br>
<br>
TL;DR: The pointee type has no (or worse, misleading) semantics and <br>
forces a load of bitcasts.  Opaque pointers remove this.<br>
<br>
David<br>
<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank" rel="noreferrer">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>