<div dir="ltr"><div dir="ltr">On Thu, Nov 7, 2019 at 10:23 AM Michael Van Canneyt <<a href="mailto:michael@freepascal.org">michael@freepascal.org</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
If I understood Sven's example correct, then the compiler does exactly this<br>
already.<br></blockquote><div><br></div><div>It does in the sense of *code generation* for things that are specifically compiler intrinsics (which I was aware of), but not in a sense that makes the issue Ryan was posting about here avoidable. Maybe this will explain what I'm trying to get at a bit better:</div><div><br></div><div>program Example;<br><br>{$mode ObjFPC}<br><br>// Without actually specializing and using GDiv,<br>// this program compiles fine.<br><br>generic function GDiv<T>(const A, B: T): T; inline;<br>begin<br> if GetTypeKind(T) in [tkInteger, tkInt64, tkQWord] then<br> Result := A div B<br> else if GetTypeKind(T) = tkFloat then<br> Result := A / B<br> else<br> Result := Default(T);<br>end;<br><br>// However, once we do specialize it...<br><br>procedure UseGDiv;<br>begin<br> // Example.pas(13,17) Error: Incompatible types: got "Double" expected "Int64"<br> WriteLn(specialize GDiv<Int64>(1, 2));<br> // Example.pas(11,17) Error: Operator is not overloaded: "Double" div "Double"<br> WriteLn(specialize GDiv<Double>(1, 2));<br>end;<br><br>// Note: I'm fully aware that having the *normal* if-statement work in such a way that the<br>// the above would compile is neither feasible or a good idea. However, imagine something<br>// like the following hypothetical version of GDiv, which would rely on the conditional<br>// compilation aspect of the scanner to be aware of more than it currently is, and also<br>// for the conditional compilation syntax to be somewhat more advanced:<br><br>generic function GDiv<T>(const A, B: T): T; inline;<br>begin<br> // Here, we're doing precisely the same kind of thing that is currently<br> // possible with SizeOf, Declared, Defined, and so on.<br> {$IF GetTypeKind(T) in [tkInteger, tkInt64, tkQWord]}<br> Result := A div B<br> {$ELSEIF GetTypeKind(T) = tkFloat}<br> Result := A / B<br> {$ELSE}<br> Result := Default(T);<br> {$ENDIF}<br>end;<br><br>begin<br>end.<br></div><div><br></div><div>Of course, implementing that kind of thing in the scanner would likely be far more difficult than implementing it as something that happens in "normal" code, via some syntax or perhaps intrinsic that makes it distinctively a fully-statically-considered conditional, as opposed to a partially-statically considered one as is the case with normal "if".</div></div></div>