http://docwiki.embarcadero.com/RADStudio/XE3/en/WEAKLINKRTTI_directive_(Delphi)


http://docwiki.embarcadero.com/RADStudio/XE3/en/WEAKLINKRTTI_directive_(Delphi)

Because deferring reference validation until runtime is that safe.

Comments

  1. That image is a good summary for any kind of RTTI binding!

    ReplyDelete
  2. Power or Security, you must choose ;)

    ReplyDelete
  3. The image for me is good on both sides : what if i want to reuse the 3rd link at left ?

    ReplyDelete
  4. I don't understand what you mean by deferring validation. If I understand correctly the directive allows you to avoid linking in all RTTI-accessible methods - it's there for you, if you know the executable doesn't need to invoke methods by RTTI, to strip them, making the size of the executable smaller. There is no validation, the code is simply not linked in. An attempt to invoke a non-existent method at runtime would fail - but you know already that there are no such attemtps.

    ReplyDelete
  5. Using RTTI to reference a property by name is deferring validation of that name until runtime.   I.e. you don't get a compiler warning if you mistyped the name.

    We need a way to reference properties (and methods) where the compiler will use a magic keyword to inject the name based on the source code name, and not a hand coded string literal.

    ReplyDelete
  6. Ah OK, so you meant RTTI itself, not the directive.

    ReplyDelete
  7. Ondrej Kelle - Well, RTTI is a good thing, and the directive exists to allow us to keep or drop code that may or may not be called through string literals.

    It is the concept of string literals that are validated at runtime only which annoys me.  

    I mean - we intentionally name the properties or methods in a string literal, where we should be able to instruct the compiler to pass the correct reference.

    That way, it would actually be checked at compile time, and not be missed after misspelling or renaming a property or method.

    ReplyDelete
  8. Well the whole point of RTTI is to deal with bindings the compiler knows nothing about, if the compiler can know about it, then why use RTTI in the first place?

    ReplyDelete
  9. Because we do want late / dynamic binding and there is no other mechanism available, except explicit setters and getters.

    ReplyDelete
  10. I guess I'm missing something here, late binding is for when you don't know what to bind at compile time, when you do know, it sounds like a complex solution to a simple problem.
    At worst, use a code generator that spits code from your a binding model, you'll get high flexibility and full compile-time checks means you can drastically cut down runtime errors of all kinds.

    ReplyDelete
  11. Example - Today I have a input validation framework that is set up in code.  It hooks into the various edit controls and populates, checks, and returns the value from the control and change colors and focus depending if the input is accepted or not.  

    I can use explicit setters and getters to make it happen,

    RegisterInput(Edit1,
      function: Integer
      begin
         _Result := MyProperty;_
      end,
      procedure (value: Integer)
      begin
        MyProperty := value;
      end);


    or I can use RTTI - but for the latter, I can't pass a property name without using a string.

    RegisterInput(Edit1, 'MyProperty');

    And this can break during refactoring :(

    Alternative 1: Compiler Magic to create string from reference

    RegisterInput(Edit1, %MyProperty);

    The % operator could generate a string literal from the variable, property or method named.

    Alternative 2: Generated Proxy

    An even better method would be if I could pass MyProperty to get a generated proxy variable from which I later could glance type and name

      procedure TInput.RegisterInput(Control: TControl; Property: TRTTIDescriptor);

    simplifying the call to

    RegisterInput(Edit1, %MyProperty);

    The % operator would create an RTTI descriptor of some sort.

    Writing a code generator for this kind of setup would be far from trivial.  Regardless of method, the idea is to be able to avoid string literals for late binding.

    ReplyDelete
  12. The code generator for the code from your first snippet looks rather simple, so I assume there is more happening than simple setter/getter? otherwise, maybe you meant the complexity in figuring what needs to be generated?

    If so your code generator could simply be run under a special build with full RTTI enabled, and generate the code from that RTTI.
    Your regular builds would use the generated code only, so no more magic strings or RTTI, but solid types instead.
    Using RTTI to generate the code means you don't have any kind of complex code parsing or interpretation to do, since you just reuse the work of the Delphi compiler.
    And using generated code means your regular builds are statically checked, and won't break under refactoring or because of magic strings.

    So that adds an extra compilation step, but you've got something that is more resilient, more strongly checked, and probably faster as a bonus. And chances are the code generator using RTTI could be simpler as well than your existing RTTI solution, since the generator would be essentially dumb loops and enumerators, with no consistency checks or subtleties.

    ReplyDelete
  13. There is an optional validator as well which allow me to do biz.logic checking beyond input to variable conversion and range checks, as well as OnChange events when the value is both changed and validated.  It is possible that a code generator would do the job - but I am already sitting in my favorite code generator and would like to avoid yet another kludge.

    It works great as is, but there is a little to much scaffolding code to my liking, and using RTTI string literals will not be solid without that code generator kludge.

    ReplyDelete
  14. IME, a proper code generator can be much less of kludge than complex scaffolding around RTTI.

    In the end, it all boils down to how much human-made code you need to do the job, and how complex that code is. Dumb code generators do not rank very high on the complexity scale in my book, while dynamic scaffolding around RTTI certainly does, and RTTI scaffolding can also be a major pita to debug through, the RTTI structures are very complex, and methods calls going through RTTI can be a mess to step through or look at in the stack inspector.

    ReplyDelete

Post a Comment