Avoiding "Error: Calling convention doesn't match forward" in FPC mode

Avoiding "Error: Calling convention doesn't match forward" in FPC mode

unit Unit1;

{$MODE FPC}
{$MODESWITCH REPEATFORWARD OFF} // doesn't make the error go away

interface

procedure test_proc;stdcall;

implementation

procedure test_proc;//stdcall;
begin
// whatever
end;

end.

除非我取消注释 "stdcall;" 对程序执行的注释,否则前一个单元将无法编译。如果我切换到 {$MODE DELPHI},这将与我取消对实现 stcall 的注释一样工作,但我想知道是否可以在 {$MODE FPC} 中省略实现时的 stdcall。

文档中的parser messages部分对这个问题很清楚(我强调的):

Error: Calling convention doesn’t match forward

This error happens when you declare a function or procedure with e.g. cdecl; but omit this directive in the implementation, or vice versa. The calling convention is part of the function declaration, and must be repeated in the function definition.

这是编译器解析器所必需的,没有解决方法(正如您已经提到的,使用 {$MODE DELPHI} 除外)。在 pdecsub.pas 单元中,这个错误的来源是这个块(由我格式化、缩短和评论):

// this compares calling conventions in the declarative and implementation parts; if
// the conventions differ, then...
if (fwpd.proccalloption <> currpd.proccalloption) then
begin
  // if {$MODE DELPHI} is used, then...
  if (m_delphi in current_settings.modeswitches) then
  begin
    // if the implementation part of the function doesn't contain calling convention
    // then assign it the one from the declarative part
    if not (po_hascallingconvention in currpd.procoptions) then
      currpd.proccalloption := fwpd.proccalloption
    else
    // otherwise check if the declarative part has calling a convention and if not,
    // assign it the one from the implementation part
    if not (po_hascallingconvention in fwpd.procoptions) then
      fwpd.proccalloption := currpd.proccalloption
    else
    // this smells like dead code, because how could calling conventions differ but
    // neither declarative nor implementation part of a function would have calling
    // convention specified ?
    begin
      // this returns 'Calling convention doesn't match forward' for {$MODE DELPHI}
      MessagePos(currpd.fileinfo, parser_e_call_convention_dont_match_forward);
      tprocsym(currpd.procsym).write_parameter_lists(currpd);
      currpd.proccalloption := fwpd.proccalloption;
    end;
  end
  else
  // mode other than {$MODE DELPHI} is used...
  begin
    // this returns 'Calling convention doesn't match forward' with no mercy
    MessagePos(currpd.fileinfo, parser_e_call_convention_dont_match_forward);
    tprocsym(currpd.procsym).write_parameter_lists(currpd);
    currpd.proccalloption := fwpd.proccalloption;
  end;
end;