8

Do you know why when declaring local const vars, the script cannot compile? Sorry, I know very little pascal and cannot figure out why this is not working!

This example (see function CircleArea) shows that my syntax should be fine. http://www.tutorialspoint.com/pascal/pascal_quick_guide.htm

This is what I am trying to do:

//---placed within [Code]
procedure MyLog(const _functionName, _msg: String);
begin
  Log(_functionName + '(): ' + _msg);
end;

function MyExec(const _filename, _params, _dir: String): Boolean;
const // <--- compilation fails in this line!
  MethodName = 'MyExec';
var
  ResultCode: Integer;
begin
  MyLog(MethodName, _filename);
  // ... invoke Exec(), etc. ...
end;
//---
fubar
  • 338
  • 1
  • 6
  • 20

2 Answers2

12

You were trying that right. If Inno Setup were using Pascal it would even work, but since it is based on a custom Pascal Script language with limitation on declaring local constants, you can't do it that way. You must define your constant globally instead:

[Code]
const
  MethodName = 'MyExec';

function MyExec(const _filename, _params, _dir: String): Boolean;
var
  ResultCode: Integer;
begin
  MyLog(MethodName, _filename);
  // ... invoke Exec(), etc. ...
end;
TLama
  • 75,147
  • 17
  • 214
  • 392
  • I understand. Is there any clever workaround, since global const will not be a solution here! How can I declare a simple variable inside var and initialize it in one step? – fubar Sep 12 '13 at 18:06
  • 3
    Unfortunately, even this `var X: Integer = 0;` is not allowed. The only way I can think of (considering preprocessor as well) is to declare the variable in the `var` section and initialize its value at the beginning of the function body. – TLama Sep 12 '13 at 18:08
1

You can use #define to define "local" constants and then use ExpandConstant('{#ConstantName}') whenever you need the value of that constant.

function MyExec(const _filename, _params, _dir: String): Boolean;
var
  ResultCode: Integer;
begin
  #define MethodName 'MyExec'

  MyLog(ExpandConstant('{#MethodName}'), _filename);
  // ... invoke Exec(), etc. ...
end;

Note that the constant isn't actually local, because it is just a preprocessor definition. So the functions after MyExec could refer to the constant as well, which might be a potential cause of error (but isn't worse than defining a real global constant). You can redefine the same constant in another function or procedure without causing a compile error though.

function MyExec(const _filename, _params, _dir: String): Boolean;
begin
  #define MethodName 'MyExec'

  MyLog(ExpandConstant('{#MethodName}'), _filename);
end;

function MyExec2(const _filename, _params, _dir: String): Boolean;
begin
  // if you forget to put the next line, it will log 'MyExec'!!!
  #define MethodName 'MyExec2'

  MyLog(ExpandConstant('{#MethodName}'), _filename);
end;

For added safety, you might want to #undef the "local" constant at the end of the function, in which case InnoSetup would cause a compile error if you'd try to reference it in the next function.

function MyExec(const _filename, _params, _dir: String): Boolean;
begin
  #define MethodName 'MyExec'

  MyLog(ExpandConstant('{#MethodName}'), _filename);

  #undef MethodName
end;

function MyExec2(const _filename, _params, _dir: String): Boolean;
begin
  // Forgot to define MethodName, but InnoSetup will cause an error
  // "undeclared identifier: MethodName".
  MyLog(ExpandConstant('{#MethodName}'), _filename);
end;
zett42
  • 25,437
  • 3
  • 35
  • 72