Thursday, January 14, 2010

Internal Compiler Error (ICE) in BCC32 of C++ Builder 2010

An excellent write-up of ‘What is an Internal Compiler Error?’ by David Dean (an Embarcadero C++ QA Engineer) is a must-read if you do not know what an ICE is, apart from it giving you error message such as this, “[BCC32 Fatal Error] FileA.cpp(56): F1004 Internal compiler error at 0x59650a1 with base 0x5900000”.

CB2010 seems to be more prone to encountering ICE, for reasons which are beyond my understanding. However, with a lot of struggle and time spent to get my projects compiled, I’ve found a few settings that are vital to avoid ICE.

The first thing I’d do is disable smart cached precompiled headers (command line: -Hs-). I’ve found that this option, combined with Debugging | Expand inline functions and/or Optimizations | Expand common intrinsic functions (implicit via Generate fastest possible code) is the root of all evil. Disabling the former will allow the latter two to be enabled, thus taking advantage of the new optimization featured in BCC32 v6.21 of CB2010. In fact, I’ve made all my projects default to this configuration. If you still get ICE, then start disabling the other two as well. Even if you get it to compile after disabling either or both of them, you’d still want to submit a QC entry (a bug report). To do this, follow the instructions in the above link (David Dean’s page about ICE).


ISL said...

Thanks very much for posting this info - we've suffered quite a bit from internal compiler errors and switching off the pre-compiled headers option seems to do the trick.

Anonymous said...

I also had a ICE error on a function using __closure.
Disabling smart chached precompiled headers solved my problem.
Thanks a lot!

GB said...

It's helped me on C++ Builder XE2, too.
Thanks for helping.

Anonymous said...

Just got me out of a nasty hole with C++ Builder 2010. Many thanks.

Santosh Thankachan said...

Excellent, We were trying to do some changes in the code to Fix these internal Compiler issues in our XE3 Build (strangely these were coming only for Release builds in our case and not Debug builds)but this solution just worked.

Thanks for sharing this information Zach.

luaphacim said...

That post isn't available anymore, so I thought I would add text from here for posterity.

The documentation team recently asked me to look over a help topic about Internal Compiler Errors. The content included no information for C++ users, so I wrote this quick draft. I hope they’ll do a better job than I did, but since this topic comes up often enough in the newsgroups, I figured posting it in my blog would be a good point of reference when the topic does come up

There are three kinds of errors that the C++ compiler generates that we group together as ICEs:

[C++ Fatal Error] (): F1001 Internal code generator error

[C++ Fatal Error] (): F1004 Internal compiler error

internal backend error

All three of these result from bugs in the compiler. The and elements are the point in your source code that the compiler was parsing prior to the error, but may or may not indicate the source of the problem. The element is specific information to tell the compiler engineers what the compiler was trying to do when the error occurred.

What to do if you encounter an internal compiler error

1) remember that your code may not be at fault.
2) try a clean build
3) try a command line build
4) analyze the source to narrow the problem
5) submit a bug report

How to perform a clean build:

1. right click on the project in the project manager and select "clean"
2. check the directory structure to make sure there are no .obj .tds .dcu .#* .pch or .csm files associated with your project
3. Choose Build from the project menu.

How to do a command line build:

1. You can copy the compiler’s command line from the Output tab in the messages pane and use that in a command shell or
2. Choose the "Rad Studio Command Prompt" from your start menu and then type msbuild yourproject.cbproj

If neither a clean build nor a command line build resolves the problem, you may want to analyze the source code to narrow the problem down.

1. Preprocess the file which is mentioned in the error message. This can be done by either right clicking on the file in the project manager and choosing preprocess, or by going to the command line and replacing the compiler (bcc32.exe) with the preprocessor (cpp32.exe) in the command to compile the file. This will generate a file with no external dependencies for compilation and may be a very large file.

2. compile the preprocessed file with the -P switch If this is sufficient to reproduce the problem, you may go straight to step 4.

3. if the .i file compiled correctly, there may be additional switched needed to reproduce the problem. recompile the .i file adding any switched used for the original command line build until you determine which switches are needed to reproduce the problem.

4. This is enough information to file a bug report. If you do not wish to narrow down the problem any further please go to the instructions for filing a bug report.

5. You can delete anything after the line where the error occurs and any comments.

6. Start to comment out function bodies and other portions of code which may not have anything to do with the problem.

7. as you determine portions which are not necessary to reproduce the problem, you may delete those sections from the .i file.

8. Once you have narrowed down the elements of code necessary to reproduce the problem, you can then submit a bug report and analyze the type of constructs used to try and find a workaround

How to file a bug report:

1. Choose Quality Central from the Tools menu in the IDE.
2. Click on the ‘+’ button to create a new report
3. Choose C++Builder as the project
4. Choose Compiler/C++ as the area
5. Enter the command line needed to reproduce the error in the steps of the bug
6. attach the .i file
7. click the check mark button to save the report.