Quick quiz

Consider this unit:

unit CCR;

interface

type
  SysUtils = record
    const EmptyStr = 'Overridden';
  end;

implementation
end.

If the constant on the record type hurts your eyes (or you still use an ancient Delphi version), use this instead –

unit CCR;

interface

type
  TSysUtils = record
    EmptyStr: string;
  end;

const
  SysUtils: TSysUtils = (EmptyStr: 'Overridden');

implementation
end.

Now, consider this test project:

program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, CCR;

begin
  WriteLn('SysUtils.EmptyStr = "', SysUtils.EmptyStr, '"');
  ReadLn;
end.

Without running the application, would you know for sure what string will be outputted (i.e., “” or “Overridden”)? Hint: the order of the uses clause may or may not be a clue here.

Bonus question: might the Free Pascal compiler behave differently with such code? (You’ll have to use the second variant of CCR.pas to test using FPC mind.)

Advertisements

7 thoughts on “Quick quiz

  1. It makes sense, actually. Given that the units act as name spaces, specifying a name space should put its content in scope. If the compiler did not work this way, you’d get completely orphaned code that cannot be accessed.

    For example, suppose I declared a variable named EmptyStr in CCR. With the way the compiler works, you can access either SysUtils.EmptyStr, CCR.SysUtils.EmptyStr, or CCR.EmptyStr by specifying the full path. You can also access CCR.EmptyStr by omitting the name space, based on CCR’s placement in the uses clause.

    Now if the compiler gave preference to the content of the CCR namespace, you’d only be able to access CCR.SysUtils.EmptyStr and CCR.EmptyStr. SysUtils.EmptyStr would be completely unaddressable. So if FPC did it differently, FPC would be wrong. 🙂

    We just get caught out by these little things because we don’t normally specify the name space, but that doesn’t mean the compiler is wrong.

    • “It makes sense, actually.”

      Well, I can easily enough rationalise it myself, but it’s still not what I expected, given the general rule about the order of the uses clause.

      “For example, suppose I declared a variable named EmptyStr in CCR.”

      Ah, very good – that’s a rather better reason than the one I had in mind!

      “So if FPC did it differently, FPC would be wrong.”

      It does the same actually, though given a debate I’ve been having with FPC/Lazarus folks in non-tech (ahem…), I was thinking it might be different.

      “We just get caught out by these little things because we don’t normally specify the name space, but that doesn’t mean the compiler is wrong.”

      Oh, I certainly wouldn’t say it’s ‘wrong’. Lot’s of unexpected things aren’t ‘wrong’…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s