Почему я получаю ошибку "Слишком много локальных констант"?
Delphi 2009 сообщает об ошибке E2283: [DCC Error] outputcode.pas(466): E2283 Слишком много локальных констант. Используйте более короткие процедуры
Delphi 2007 компилируется просто отлично. Я не могу найти изобилие локальных констант, это короткая (500 строк) единица. Вы видите какое-нибудь изобилие констант или литералов, к которым я могу обратиться?
procedure TOutputCodeForm.FormCreate(Sender: TObject);
var
poParser : TStringStream;
begin
if ( IsWindowsVista() ) then
begin
SetVistaFonts( self );
end;
poParser := TStringStream.Create( gstrSQLParser );
SQLParser := TSyntaxMemoParser.Create( self );
SQLParser.RegistryKey := '\Software\Advantage Data Architect\SQLSyntaxMemo';
SQLParser.UseRegistry := True;
SQLParser.CompileFromStream( poParser );
FreeAndNil( poParser );
poParser := TStringStream.Create( gstrCPPParser );
cppParser := TSyntaxMemoParser.Create( self );
cppParser.RegistryKey := '\Software\Advantage Data Architect\SQLSyntaxMemo';
cppParser.UseRegistry := True;
cppParser.CompileFromStream( poParser );
FreeAndNil( poParser );
poParser := TStringStream.Create( gstrPasParser );
pasParser := TSyntaxMemoParser.Create( self );
pasParser.RegistryKey := '\Software\Advantage Data Architect\SQLSyntaxMemo';
pasParser.Script := ExtractFilePath( Application.ExeName ) + 'pasScript.txt';
pasParser.CompileFromStream( poParser );
{* Free the stream since we are finished with it. *}
FreeAndNil( poParser );
poCodeOutput := TSyntaxMemo.Create( self );
poCodeOutput.Parent := Panel1;
poCodeOutput.Left := 8;
poCodeOutput.Top := 8;
poCodeOutput.Width := Panel1.Width - 16;
poCodeOutput.Height := Panel1.Height - 16;
poCodeOutput.ClipCopyFormats := [smTEXT, smRTF];
poCodeOutput.Font.Charset := ANSI_CHARSET;
poCodeOutput.Font.Color := clWindowText;
poCodeOutput.Font.Height := -11;
poCodeOutput.Font.Name := 'Courier New';
poCodeOutput.Font.Style := [];
poCodeOutput.GutterFont.Charset := DEFAULT_CHARSET;
poCodeOutput.GutterFont.Color := clWindowText;
poCodeOutput.GutterFont.Height := -11;
poCodeOutput.GutterFont.Name := 'MS Sans Serif';
poCodeOutput.GutterFont.Style := [];
poCodeOutput.HyperCursor := crDefault;
poCodeOutput.IndentStep := 1;
poCodeOutput.Margin := 2;
poCodeOutput.Modified := False;
poCodeOutput.MonoPrint := True;
poCodeOutput.Options := [smoSyntaxHighlight, smoPrintWrap, smoPrintLineNos, smoPrintFilename, smoPrintDate, smoPrintPageNos, smoAutoIndent, smoTabToColumn, smoWordSelect, smoShowRMargin, smoShowGutter, smoShowWrapColumn, smoTitleAsFilename, smoProcessDroppedFiles, smoBlockOverwriteCursor, smoShowWrapGlyph, smoColumnTrack, smoUseTAB, smoSmartFill, smoOLEDragSource];
poCodeOutput.ReadOnly := False;
poCodeOutput.RightMargin := 80;
poCodeOutput.SaveFormat := sfTEXT;
poCodeOutput.ScrollBars := ssBoth;
poCodeOutput.SelLineStyle := lsCRLF;
poCodeOutput.SelStart := 3;
poCodeOutput.SelLength := 0;
poCodeOutput.SelTextColor := clWhite;
poCodeOutput.SelTextBack := clBlack;
poCodeOutput.TabDefault := 4;
poCodeOutput.TabOrder := 0;
poCodeOutput.VisiblePropEdPages := [ppOPTIONS, ppHIGHLIGHTING, ppKEYS, ppAUTOCORRECT, ppTEMPLATES];
poCodeOutput.WrapAtColumn := 0;
poCodeOutput.OnKeyDown := FormKeyDown;
poCodeOutput.ActiveParser := 3;
poCodeOutput.Anchors := [akLeft, akTop, akRight, akBottom];
poCodeOutput.Parser1 := pasParser;
poCodeOutput.Parser2 := cppParser;
poCodeOutput.Parser3 := SQLParser;
SQLParser.AttachEditor( poCodeOutput );
cppParser.AttachEditor( poCodeOutput );
pasParser.AttachEditor( poCodeOutput );
poCodeOutput.Lines.AddStrings( poCode );
if ( CodeType = ctCPP ) then
poCodeOutput.ActiveParser := 2
else if ( CodeType = ctPascal ) then
poCodeOutput.ActiveParser := 1
else
poCodeOutput.ActiveParser := 3;
MainForm.AdjustFormSize( self, 0.95, 0.75 );
end;
6 ответов
Определяется Win32, могут ли константы быть из всех включенных модулей.
я бы выполнил бинарный поиск: продолжай вырывать половину модуля, пока он не скомпилируется, затем добавь обратно.
Да, это отстой, но это одна из особенностей отладки внутренних ошибок компилятора BorlandCodeGaembarcadero.
Прежде чем утверждать, что это ошибка компилятора или обратиться за помощью, я бы серьезно постарался организовать и очистить мой код.
Я бы создал специальные подпрограммы для каждой части FormCreate вместо этой вашей огромной сумки. - SQLParseInit
- cppParseInit
- pasParseInit
- CodeOutPutInit <- +++++ много констант там
И посмотрите, если 1, в частности, вызывает проблемы.
И было бы неплохо создать минимальный случай, с как можно меньшим количеством сторонних зависимостей, чтобы позволить другим воспроизвести его и посмотреть, действительно ли это ошибка или просто плохой код.
А также удалите эти $IFDEF... Просто предоставьте реальный код, который вызывает это поведение без всего беспорядка.
Добавлено: поскольку это работает в D2007, но не в D2009, я также дважды проверю, чтобы все библиотеки / сторонние компоненты, которые вы включили в свой код, были правильно перенесены в D2009. (разверните этот cppParser)
Я бы посмотрел на строку "poCodeOutput.Options:= [xx....]" Похоже, слишком много опций в наборе в одной строке кода.
Возьмите эту строку и посмотрите, получите ли вы ошибку.
Я нашел метод (FormCreate), который является проблемой, и проводил рефакторинг, но независимо от того, насколько маленьким я делаю куски, у компилятора все еще есть проблема, если я не удаляю часть кода.
Франсуа спасибо, но я сделал рефакторинг кода и все еще получаю ошибку. Если он построен на D2007, а не на D2009, это кажется мне подозрительным.
procedure TOutputCodeForm.FormCreate(Sender: TObject);
begin
if ( IsWindowsVista() ) then
begin
SetVistaFonts( self );
end;
SetupParser( SQLParser, gstrSQLParser, '' );
// unresolved jmu - have to comment this out for now or delphi will complain
// that there are too many literals in this file. Seems like a delphi bug
// since this builds in older versions, and I've already refactored it.
//SetupParser( cppParser, gstrCPPParser, '' );
SetupParser( pasParser, gstrPasParser, ExtractFilePath( Application.ExeName ) + 'pasScript.txt' );
SetupCodeOutput( poCodeOutput );
SQLParser.AttachEditor( poCodeOutput );
cppParser.AttachEditor( poCodeOutput );
pasParser.AttachEditor( poCodeOutput );
poCodeOutput.Lines.AddStrings( poCode );
if ( CodeType = ctCPP ) then
poCodeOutput.ActiveParser := 2
else if ( CodeType = ctPascal ) then
poCodeOutput.ActiveParser := 1
else
poCodeOutput.ActiveParser := 3;
MainForm.AdjustFormSize( self, 0.95, 0.75 );
end;
Из справки:
Одна или несколько ваших процедур содержат так много строковых константных выражений, что они превышают предел внутренней памяти компилятора. Это может происходить в коде, который генерируется автоматически. Чтобы исправить это, вы можете сократить ваши процедуры или объявить идентификаторы константы вместо того, чтобы использовать так много литералов в коде.
Поэтому, возможно, попробуйте поместить некоторые из этих строк в переменные или другие переменные (не локальные).
Учитывая, что проблема возникает только в одном из ваших компиляторов / установок Delphi, я задаюсь вопросом, связано ли это с проблемой установки компонента. Вы пробовали просто создать базовую форму, которая использует статические версии всех компонентов, которые вы создаете динамически? (TSyntaxMemoParser и т. Д.).
(Используете ли вы эти версии Delphi на отдельных машинах / кстати, виртуальной машине? Можно сэкономить много хлопот, если вы используете много сторонних компонентов и более чем одну версию Delphi)