8

I am unable to figure out how to change default build/compile settings. The little default checkbox in the lower left of the project options dialog is gone. The documentation states:

The Default checkbox that appeared at the lower edge of many Project Options pages has been removed from the product. If you want to specify options as the default for multiple projects, the suggested alternative is to use option sets instead.

I'm going round and round about "Options Sets", "Configuration Manager" etc.. Is this even possible? What does "specifying options as the default for multiple projects" mean? If I have multiple projects then that means those projects and their options exists, how can I set a default value to something already set? What about new projects?

Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • I don't think you can get new projects to use an option set by default. But once you have option sets in place it's easy to add them to your new project. I think that's what you are intended to do now. In other words the old feature of being able globally to change the project options for newly created projects really has gone. You could try adding your own whole app template but I could never make that feature work the way I wanted it to. – David Heffernan Apr 13 '12 at 07:29
  • @David - I don't understant why they would recall our ability to have our default options.. Sure I can modify my settings for every new project (after a while I'll memorize what to apply everytime), but it's not like that I use 'File' -> 'New Project' for only *production* projects. I create a good few projects everyday to have a quick test of this or that, and testing is debugging, and now I have to apply my options everytime since default options are *wrong* (can it be right for everyone?). – Sertac Akyuz Apr 13 '12 at 07:56
  • I think that the now removed feature had its own weaknesses because, once you had changed defaults, it meant that it was harder for you to work out what the official default options were. But I agree that the need for quickly creating projects with a specific user-specified configuration is important. I think my answer gives a reasonable workaround. – David Heffernan Apr 13 '12 at 08:40
  • 1
    @David - They could add a feature instead of removing one by solving that weakness providing a "reset defaults" button. – Sertac Akyuz Apr 13 '12 at 11:32
  • Yeah, that would have been an option for them. – David Heffernan Apr 13 '12 at 11:48

3 Answers3

6

That feature really has gone and there is nothing like it any more in the product, to the very best of my knowledge. I think the best you can do is as follows:

  1. Create a new project.
  2. Change the project settings to whatever you want them to be.
  3. Change anything else in the default project that you don't like, for example { Private declarations }.
  4. Add this project to the repository.
  5. use File | New | Customize to move this project template onto the File | New menu for easy access.
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • This has the downside of being forced to save the project while creating, but also have other pluses as you mention in '3'. I'll play around a while to see if this is better than assigning an option set to a new project.. You're right in that this is a reasonable workaround, thanks! – Sertac Akyuz Apr 13 '12 at 11:36
  • I think I'll go with the 'options' in the end. Otherwise because of forcing to save, I'll quickly fill my disk with trash or I'll lose potentially useful code fragments. Meanwhile I've put the debug .dcu path *before* the library path. At least I'll be tracing VCL/RTL code without any effort. Hope I'll not forget to remove the path for release builds.. – Sertac Akyuz Apr 13 '12 at 18:01
  • Holly Jesus - Why Embarcadero did that? – Gabriel Jan 13 '15 at 20:42
  • @Altar Don't know. I think it's a good move because I never liked the feature. I never liked that the default settings for new projects could vary from machine to machine, user to user. But I don't create a lot of new projects. – David Heffernan Jan 13 '15 at 21:13
  • If you set those default options for your Delphi, in your computer and don't reinstall Delphi every year, then they are fixed/won't change :) – Gabriel Jan 13 '15 at 21:24
  • @Altar I have multiple machines with Delphi installed, and a team of developers. I like everyone to be on the same page. – David Heffernan Jan 13 '15 at 21:34
  • Yes. As I said, each developer could set (after first Delphi install) its default project options to the same predefined values. All programmers will have therefore the same project options when they start a new project. But I do understand that in a big company that focuses on a single large project, default project options are not relevant/important. – Gabriel Jan 13 '15 at 21:41
2

Project->Options->Target. You can set up a base configuration, and then provide different options that differ from the base for Debug and Release. You can also create custom option sets, which means that they're different from the standard Debug and Release. You can also have different configurations based on different targets (VCL app's Debug build has different options than a FMX app's Debug build, etc.)

To change the default options first starts with defining "default". You can start as low as the "base configuration" through Project->Options->Delphi Compiler, and then choosing the All Configuration target. You can refine it somewhat by altering the base configuration for the Debug and Release configurations. You can also define your own option sets, using the Save button next to the Target list.

Your specific question about "specifying options as the default for multiple projects" means is the base configuration. From there, you refine those base options to give you debug settings and release settings (which can also be saved as your initial defaults, and refined on a per-project basis).

So, for a specific answer, you can change the default by modifying the base configuration, or by getting more specific by modifying the debug or release configurations that inherit from that base, depending on what your end result needs to be and what you're trying to accomplish.

Ken White
  • 123,280
  • 14
  • 225
  • 444
  • Ken, please bear with me a little for I think I'm particularly dumb at this time. I'm trying to implement your explanation but failing, the option set I'm saving is not used by new projects, and I can't seem to edit the base configuration. Can you please tell me steps for what it would take to when I select 'File -> New VCL Application' that 'Use debug .dcus' would be checked for 'Debug configuration'? – Sertac Akyuz Apr 13 '12 at 03:28
  • I think David's solution will work. I'll extend my answer when I have a little time (in a couple of hours) with info on doing what you ask for in your comment. :) – Ken White Apr 13 '12 at 12:39
  • Maybe a screenshot or two wouldn't be remiss since this is an area of the IDE people don't often twit around in. – Warren P Apr 13 '12 at 13:54
  • Thanks Ken, your information is helpful to me anyway as a general guide to how this all works now. – Sertac Akyuz Apr 13 '12 at 18:27
  • 2
    I've spent the last hour or so trying to configure my XE2 IDE to default to using debug .dcus when creating a new project and choosing the `Debug` configuration, and I've come to the conclusion that David is right. :) The only way to do this consistently is to edit the configuration options of a new, empty project, save the changed options (Project->Options, make changes, choose `Save...` next to the `Target` dropdown, save to a `*.optset` file). You can then apply this as your default option set to new projects, but you have to manually apply using the same dialog. Still looking into this... – Ken White Apr 13 '12 at 19:18
  • @Ken: Did you get anywhere with this Ken? I've spent a day with XE2 and XE3 trying an option set file as a reference (which looks rather nice) but relative paths in it seem broken. Apply it as 'modify values' seems to work fine. – Brian Frost Oct 29 '12 at 17:11
  • @Brian: No, I finally just gave up. :-) I'm hoping they do something in future versions to make this easier; I haven't had the chance to play a lot with XE3 yet, so I don't know if there are improvements in this area there or not. – Ken White Oct 29 '12 at 17:14
  • Any news about this issue? Has it been fixed in Delphi XE7? It seems it is still broken/missing. – Gabriel Jan 13 '15 at 20:41
1

I have a "default" project. So, I never start a new project, instead I copy that one. That "default" project does a lot of extra stuff for me, including improved support for TApplication.

And you are indeed right, NO application/projects should ever be started without Overflow Checking, Range Checking and Assertions being turned on by default (for Debug version).

Well, there are more settings that should be turned on by default, for proper debugging.

Can be also done as David showed it (Repository). But I prefer to manually manipulate (copy) files and folders from the excellent Total Commander.


Overflow checking

This will check certain integer arithmetic operations (+, -, *, Abs, Sqr, Succ, Pred, Inc, and Dec) for overflow. For example, after a + (addition) operation the compiler will insert additional binary code that verifies that the result of the operation is within the supported range.

An "integer overflow" occurs when an operation on an integer variable produces a result that is outside the range of that variable. For example, if an integer variable is declared as a 16-bit signed integer, its value can range from -32768 to 32767. If an operation on this variable produces a result greater than 32767 or less than -32768, an integer overflow has occurred.

When an integer overflow occurs, the result of the operation is undefined and can lead to undefined behavior in the program: • Wrap-around The result might result in a wrapped-around value. This means that the number 32768 will be actually stored as 1 since it is 1 unit higher than the highest value we can store (32767). • Truncation The result may be truncated or otherwise modified to fit within the range of the integer type. For example, the number 32768 will be actually stored as 32767 since that is the highest value we can store.

Undefined program behavior is one of the worst kind of errors, because it is not an error easy to reproduce. Therefore, it is difficult to track and repair.

There is a small price to pay if you activate this: the speed of the program will decrease slightly.

IO checking

Checks the result of an I/O operation. If an I/O operation fails, an exception is raised. If this switch is off, we must check for I/O errors manually. There is a minor price to pay if you activate this: the speed of the program will decrease, but insignificantly because the few microseconds introduced by this check is nothing compared with the millisecond-range time required by the I/O operation itself (the hard drives are slow).

Range Checking

The Delphi Geek calls this “The most important Delphi setting” and I totally agree. It checks if all array and string indexing expressions are within the defined bounds. It also checks that all assignments to scalar and subrange variables are within range.

Here is an example of code that would ruin our life if Range Checking would not be available:

Type 
    Pasword= array [1..10] of byte; // we define an array of 10 elements
…
x:= Pasword[20];       // Range Checking will prevent the program from accessing element 20 (ERangecheckError exception is raised). Security breach avoided. Error log automatically sent to the programmer. Bruce Willis saves everyone.

Enabling Runtime Error Checking

To activate the Runtime Error Checking, go to Project Options and check these three boxes:

Enabling the Runtime Error Checking in ‘Project Options’ enter image description here

Assertions

A good programmer MUST use assertions in its code to increase the quality and stability of the program. Seriously man! You really need to use them.

Assertions are used to check for conditions that should always be true at a certain point in the program, and to raise an exception if the condition is not met. The Assert procedure, which is defined in the SysUtils unit, is typically used to perform assertions.

You can think of assertions as poor man’s unit testing. I strongly advise you to look deeper into assertions. They are very useful and do not require as much work as unit testing.

Typical example:

SysUtils.Assert(Input <> Nil, ‘The input should not be nil!’);

But for the program to check our assertions, we need to active this feature in the Project Settings -> Compiler Options, otherwise they will simply be ignored, like they are not there in our code. Make sure that you understand the implications of what I just said! For example, we screw up badly if we call routines that have side effects in the Assert. In the example below, during Debugging when the assertions are on, the Test() function will be executed and 'This was executed' will appear in the Memo. However, during Release more, that text will not appear in the memo because now Assert is simply ignored. Congratulations we just made the program to behave differently in debug/release mode ☹.

function TMainForm.Test: Boolean;
begin
 Result:= FALSE;
 mmo.Lines.Add('This was executed');
end;

procedure TMainForm.Start;
VAR x: Integer;
begin
 x:= 0;
 if x= 0
 then Assert(Test(), 'nope');
end;

Here are a few examples of how it can be used:

1 To check if an input parameter is within the 0..100 range:

procedure DoSomething(value: Integer);
begin
  Assert((value >= 0) and (value <= 100), 'Value out of range');
  …
end;

2 To check if a pointer is not nil before using it:

Var p: Pointer;
Begin
  p := GetPointer;
  Assert(Assigned(p), 'Pointer is nil');
   …
End;

3 To check if a variable has a certain value before proceeding:

var i: Integer;
begin
   i := GetValue;
   Assert(i = 42, 'Incorrect response to “What is the answer to life”!');
  …
end;

Assertions can also be disabled by defining the NDEBUG symbol in the project options or by using the {$D-} compiler directives.

We can also use the Assert as a more elegant way of handling errors and exceptions in some cases, as it can be more readable and it also includes a custom message, that would help the developer understand what went wrong.

Personally, I use it a lot at the top of my routines to check if the parameters are valid.

Activating this feature will (naturally) make your program slower because… well, there is one extra line of code to execute.

Nothing comes for free

Everything nice comes with a price (fortunately a small price in our case): enabling Runtime error checking and Assertions slows down our program and makes it somewhat larger.

Computers today have lots of RAM so the slight increase in size is irrelevant, so, let’s put that aside. But let’s look at the speed, because that is not something we can easily ignore:

Type                 Disabled   Enabled
Range checking       73ms         120ms
Overflow checking    580ms        680ms
I/O checking         Not tested   Not tested

As we can see the program's speed is strongly impacted by these runtime checking. If we have a program where speed is critical, we better activate “Runtime error checking” during debugging only. What I do, I also leave it active in the first release and wait a few weeks. If no bugs are reported, then I release an update in which “Runtime error checking” is off.

Personally, I leave the “IO checking” always active. The performance hit because of this check is microscopic.


Big warning:
If you have an existing project that was not so nicely written, and you activate any of the Runtime Error checking below, your program may will crash more often than usual. No, the Runtime Error checking routines did not break your program. It was always broken – you just didn’t know. The Runtime Checking routines are now finding all those places where the code is fishy and shitty and smelly. The sole purpose of Runtime Checking is to find bugs in your program.

Gabriel
  • 20,797
  • 27
  • 159
  • 293