tags:

views:

3145

answers:

66

What sort of minor annoyances do you run into using Delphi? I'm not looking for major issues such as "I want a 64-bit compiler." Just little things that can be easily worked around but still should have been implemented better so you don't have to work around them?

Marking this CW. I'm more interested in the answers than the points.

+7  A: 

One that just bugs me is SysUtils.StringReplace. The last parameter ought to be declared with a default value of [].

Mason Wheeler
i don't think i've ever passed anything besides `[rfReplaceAll]`
Ian Boyd
I use [rfReplaceAll] and [] depending on my needs. Not sure if I use one more than another.
Robert Love
Sounds like a good place to write your own MyStrUtils. :-) I've been cultivating one for years and it has dozens of great little functions in it. StringReplaceAll( blah,blah), versus StringReplaceFirst()
Warren P
+7  A: 

I want auto-invoked Code Completion to insert whatever I've selected when I type a separator - a dot, a semicolon, whatever. It does this when I invoke it manually with Ctrl-Space, but not with auto-invoke.

Michael Madsen
better yet, let me pick which keystrokes will trigger insertion
JosephStyons
QC #66613 covers this one, at least if you use the comment on that report as an elaboration.
Michael Madsen
+3  A: 

It annoys me somewhat that I can't define a floating point value in hexadecimal (hex values are interpreted as integers)

PhiS
How would you define a floating point value in hex in C?
Ken White
But floating point values are just approximations. For real work, use a integer with an implied decimal. This also solves the inability to enter values in hexadecimal. :)
skamradt
No, Skamradt, floating-point values are always exact. They may not be able to express all the decimal values you want, but the values they *can* express are exact. John Herbster has a project on Code Central that will tell you the exact decimal value of any Single or Double value.
Rob Kennedy
Easy, Ken: 0xA2.C4Ep+2f is a hexadecimal floating literal. See section 6.4.4.2 of the C99 standard. Or section 3.10.2 of the Java Language Specification.
Rob Kennedy
Why would you want to? Isn't C hard enough to read as is?
Gerry
You'd want to, Gerry, so that you can provide certain exact floating-point values that the language doesn't otherwise allow you to represent in decimal, either because it requires more digits than the parser accepts, or because the decimal-to-float conversion works in powers of 10 instead of powers of two, leading to imprecise conversions.
Rob Kennedy
+10  A: 

My biggest nitpick is the inability for the editor/debugger to sync properly when a file containing non standard CR+LF line delimiters is loaded. Unfortunately, some of the tools used to edit code do not generate the proper line endings. When a file with mismatched line endings is loaded and compiled, the blue instruction marks while debugging do not line up with the proper line of code....this makes setting break points difficult.

The solution is to save the file and reload using something like Notepad+ to convert the non-standard line endings to normal CRLF ones, then reload AND recompile the project. This unfortunately takes more time for something that should be corrected in the IDE.

(this weeks blog entry by Jeff Atwood covered this exact issue, or at least the history of why it is one).

skamradt
A: 

It's based on Pascal. :)

Seriously, I went to a Borland conference many years ago where Anders Hjelsburg was demo-ing the new Delphi (2.0) that was about to come out. People loved it, but the Q&A session was almost entirely, "Why didn't you use C?", "Will you be coming out with a C version soon?", etc.

Greg Charles
So that's why they introduced C++ builder? :-)
Giel
They've only had a C++ version since about 1996. It's called C++Builder, and it's good. Not insanely great, but good.
Roddy
Yes, in fact, that's exactly why they introduced C++ Builder. Anders explained that at the time Borland essentially had complete control of the Pascal language, since no one else was still using it, and so they could add language features as needed. It was a good point, but even after he made it, the next question was basically of a rehash of "Why not C?" (Not from me mind you. Yes, I would have preferred C, but I understood the choice of Pascal.)
Greg Charles
Because C sucks big time unless you are writing an OS. Use for what it was designed for, use higher level languages for higher level problems!
Gerry
Why is this supposed to be a nitpick? I think it's a good feature!
Loren Pechtel
IYWTPICTPIC. One of Delphis biggest strengths is its readable yet powerful syntax.
Cleggy
So, your complaint about Delphi is that it isn't C++ Builder? So what?
Rob Kennedy
Some people just don't get it.
Warren P
Oh, I get it. I agree that C is better as a systems programming language, and C++ is an ugly hybrid. I don't have any complaints per se about Delphi. I actually just wanted to relate an (I thought) amusing anecdote about the early days of Delphi, and I've inadvertently started a religious war. My apologies!
Greg Charles
You didn't cause a religious war. You caused mass confusion by giving an answer that made no sense for the question. When a posted answer doesn't actually answer the question, it gets voted down. There's no penalty to the voter when voting down a community-wiki post, so more people are likely do it.
Rob Kennedy
The fact that it didn't use C as the language would, in my mind, constitute a big selling point in those days. That people were asking for C-syntax meant that they did not understand the point of Delphi at all. The point of Delphi was to make programming *easier*, but still *powerful*. Not *hard* and *shoot-yourself-in-the-foot-powerful*.
Lasse V. Karlsen
@Lasse: You're absolutely right about that. As Paul Graham likes to say about Lisp, if people understood Delphi, they'd be using it.
Mason Wheeler
@Lasse No, we were blown away by Delphi's capabilities even in its initial release. It blew away VB since could compile into native executables, unlike VB at the time, and was also fully operational. With VB, you still had to make components in Visual C++, which you then could use in VB. However, at the time Pascal was looked on as a dying language only appropriate for teaching new programmers, and just marginally better than Basic. Despite the scorching, I'm glad I posted my comment, since it showed me that perception has changed over the years, though I'm sorry to have provoked so much ire.
Greg Charles
+13  A: 

WITH

Without a doubt :-). With is pretty evil as it leads to confusing and hard to maintain code. Of course one never uses it oneself, and undoubtedly it should be classified as a language feature you should never use, but it tends to pop up far to often in code examples, particularly for beginners who then use it liberally only to learn from experience later that this is not a good idea. OK it's a Pascal thing, but it could, should, have been dropped.

I spent a decade coding Delphi pretty intensively from version 1.0 (and I used to use Turbo Pascal too) up to 7 when I largely moved elsewhere, and in that whole time I think I found one single occasion when I needed a with to pass a pointer to the correct member of a very complex structure to a function.

Cruachan
Change the frikkin record. "with" is useful. No-one forces you to use it, what gives you or anyone else the right to force people to stop using it who have learned the self discipline to use it safely and usefully (it can be done) ?What next? Remove "pointers"? Hell, remove the inline assembler... when it comes to "dangerous" and abusable language features.. it doesn't get more dangerous than that!
Deltics
`with` makes debugging impossible, since the IDE doesn't know what variable you're hovering over.
Ian Boyd
@Deltics - give me one example where with is useful. Useful enough as IanBoyd says to be worthwhile breaking the debugger. That'll be a start.
Cruachan
Seems to me that's an argument for improving the debugger, not for removing a language feature.
Craig Peterson
@Cruachan: with cmbNames do ItemIndex := Items.IndexOf(sName); Insufficiently complex for debugging this to ever be an issue, zero symbol ambiguity potential, reduces redundant repetition thereby increasing readability and reduces the need for the amount of code to be modified should the name of the control (cmbNames) ever change.
Deltics
@Ian: If the compiler can figure it out, the debugger should be able to. As Craig says, this is a shortcoming of the debugger NOT an intrinsic fault of "with".
Deltics
The debugger not being able to understand it is just another nail in the dead horse. The real reason for the nitpick is that `with` code is hard to read.
Ian Boyd
@Deltics - your example is precisely what I would avoid as I don't think it adds anything to the readability of the code, and in fact detracts it. I'd much rather see the full dereference including in the simple cases such as this. IF Delphi implemented the member as with cmbNames do ItemIndex := Items.IndexOf(.sName); I would be less scathing
Cruachan
@Deltics: I don't use **with** ... the fact that others can use it is _precisely_ the reason it should be removed. I do sometimes maintain other people's code; and if I'm not intimately familiar with the records/classes involved (similar problem with my own code a year down the line), **with** makes the scope of identifiers _extremely_ difficult to interpret. The **with** statement also makes it possible to change the behaviour of the code in the **with** block by adding/removing attributes from the class or record definition - probably in an entirely different unit!
Craig Young
I would love a "Remove all WITH statements from this code" refactoring, ie, "make everything explicit".
Warren P
@CraigY - precisely. If there's one thing SO has taught me there's generally far too little appreciation of the need to write easily maintainable code. IMHO All programmers should be forced at some early stage in their career to work in a maintenance teem - indeed one employee I worked for made a point of giving all their trainees a 3 month period in one in their first year or two - and it's probably not a coincidence that they had one of the cleaner codebases I've ever seen.
Cruachan
@Craig - the example I provided (pretty much the only time I would use it) does not contain any hard to identify scope. Two identifiers are contained by the"with" identifier, the 3rd is clearly not. "With" can be used badly. So can the inline assembler. So can pointers. So can classes. If all you ever do is complain at people who use with instead of teaching them how to use it safely and responsibly then you can only ever expect them to use it badly.
Deltics
@Cruachan - introducing MORE places where code has to be changed is LESS maintainable. Introducing needless repetition also reduces readability - you may think it reduces ambiguity, but you should never forget that ambiguous code simply doesn't compile. Do you also insist that people explicitly parenthesise rather than relying on operator precedence? (I do this myself as a matter of course, but I just wonder if you are consistent in your philosophy or just indoctrinated to consider "with" evil, even when used responsibly).
Deltics
@Craig - what other language features do you not use that we should all have taken away from us? The inline assembler I'm guessing. All the things you attribute to "with" are laid squarely at the feet of the DEVELOPER using "with" badly. I suggest you should stop using bad developers and all sorts of problems will suddenly disappear, not just "with".
Deltics
@Deltics the fundamental issue here is that WITH is purely in there as a supposed convenience and doesn't add anything functionally -which pointers and the rest do (and I have no issue at all with some things being hard to understand/use). With your example too of course it's pretty straightforward. The issue comes when that code has been in production for several years, been maintained by half a dozen programmers some of whom had difficulty with the if statement ;-) and it's expanded from a simple construct to a mess. Then the WITH becomes not a convenience but a source of errors and bugs.
Cruachan
@Deltics And yes I do insist on parenthesised conditions and always using delimiters around if statements for similar reasons - experience shows that insisting on these language features reduces long term maintenance issues. Sure you may be an excellent coder who can handle anything correctly but if you work in any sort of corporate environment - be it employee or contractor - you have no control over what eejit will maintain your code in future and it's your professional responsibility to reduce the likelihood of bugs being introduced. Clear code formatting, and this effectively is an aspect
Cruachan
@Deltics of this goes a long way to minimise that. Indeed on of the reasons I'm besmitten with Python is the requirement for formatting built into the language.Just out of interest do you set out and indent your WITH blocks in the same way as you do an if or loop?
Cruachan
@Deltics: If you understood my comment, you'd know why the example you provided **is actually** a **bad** example of **with**. First, I have to assume (<-- always a BIG problem) that `cmbNames` is a `TComboBox` (but before you plead 'Hungarian Notation', let me point out that you're using a bastardisation thereof because the true ideas behind Hungarian Notation have been largely misunderstood). Second, the **only** reason I know which identifiers do/don't belong to `cmbNames` is that I have many years experience with the _relevant aspect_ of Delphi development (see my previous comment).
Craig Young
@Deltics (cont.): Now (referring to the point about my 2nd problem with **with**): suppose you get a new UI component suite that allows combo boxes to be bound to enums. Perhaps these don't expose `Items` or `ItemIndex` because it's no longer necessary due to the enum binding. You could replace the combo and your code compiles... but wait, didn't I say `Items` and `ItemIndex` had been removed? Your code would compile if those identifiers already existed in an outer scope. Let me be clear on this: **There are no good examples of with**.
Craig Young
@Deltics: Let's consider the 'pros' you presented for using **with** in your example: `with cmbNames do ItemIndex := Items.IndexOf(sName)`. You claim the reduced repetition increases readability. I disagree, throughout the rest of the statement you have to ask yourself what is the scope of each of the identifiers: `[cmbNames?]ItemIndex := [cmbNames?]Items.IndexOf([cmbNames?]sName)`. You also suggest that maintenance is easier because less code needs to be modified if cmbNames changes. 1st, maintenance is not about how much code you type! 2nd, _basic_ refactoring editors make your point moot.
Craig Young
@Deltics: The problems with WITH have **nothing** to do with good/bad developers - so don't jump to conclusions here! WITH is itself an inherently bad construct. Back in the Pascal days WITH was not so bad; but now that we have classes and (possibly many levels of) inheritance, we have additional layers of scope. It's these scoping layers that make WITH dangerous! I have nothing against "hard to understand" features. Personally I'm unlikely to use inline assembler (because it's not as useful as you might think); but it's not nearly as dangerous as WITH... because the code is **explicit**!
Craig Young
@Deltics: Final thought... if you have an itch to use use WITH in a particular piece of code because you think it will save you a lot of "redundant repetition" - you probably need to rethink your OO design... it will save you much more!
Craig Young
With could be improved if you had the opportunity to name the thing being used, like this :with A: some.very.long.path.to.a.variable.or.method do begin A.call(arguments);
PatrickvL
+13  A: 

^Click browsing of the code usually brings you to the the wrong place (often the end of the file). it was broken in delphi 2005 and even in 2009 (haven't tried 2010).

in delphi 2009, they added a new bug--when it's busy in code completion, it often "eats" keystrokes. when it's busy you better stop typing since it's not listening anyway. mix that with slow code completion, and you have a real recipe for irritation.

one other thing--the TRibbon control is rather frail & hard to work with. i've had corrupted form files and plenty of time trying to figure out how to get the designer to let me edit/add/move something.

refactoring to add/remove parameters tends to destroy the code.

i sure wish the TActionManager showed more than just caption! how about Name, Caption, Icon, Catogory? some sorting ability sure would help too.

X-Ray
The click browsing problems are IMO just one more symptom of this archaic concept of search path, browsing path and what-not path...
Robert Giesecke
@Robert: i just use the one path, the library path.
Ian Boyd
Ctrl+Click not working is a result I think, of the same parser problems that caused Error Insight to fail. Next time you can't get Ctrl+Click to work,turn on Error INsight. The code might "okay to compile", but something has gotten twisted inside the error-insight/code-completion/code-navigation parser code.
Warren P
shortening the library path from about 38 items to 23 items seem to have helped quite a bit.
X-Ray
+57  A: 

Definitely the buggy Error Insight!

alt text

I guess anybody who uses a D2005 or newer knows this bug... you are writing code that compiles well but Error Insight tells you it can't resolve a unit name or you use an undeclared identifier etc...

This bug still exists in Rad Studio 2010! Unbelievable (I am experiencing it right now)!

To the shame of Borland/Codegear/Embarcadero/ (funny thing, this bug survived every sale :D ) a third party developer managed to fix this bug... Who doesn't know Andreas Hausladen?

Edit: This seems to be #QC33546 (the first one I found, but I bet this has been reported more than once)

Mef
i see that *ALL* the time. the procedure "1. select all, 2. copy, 3. paste" helps but it's back again soon. red lines out in the middle of white space are not uncommon.
X-Ray
Also, OleVariants using named parameters for late-bound COM, like `msw.Selection.MoveRight(Unit := wdCell);`I wish there were a directive to tell Error Insight not to try to parse certain sections, something like {$ERROR_INSIGHT OFF}
jasonpenny
For the record, there is a reason that Andreas is able to fix these things -- we work very, very, very closely with him and he has access to things most developers don't.
Nick Hodges
And I really appreciate that! Anyhow, official fixes are much more appreciated ;-)
Mef
I disagree, official fixes are for the current version only. But I'm now able to use Andy's fixes for D2007.
Sertac Akyuz
@Nick: The implication isn't that Andreas is somehow a smarter programmer because he can fix a bug while we can't. The implication is that Embargadero's own developers can't fix a after 3 major versions, while an outside developer can.
Ian Boyd
Gotta agree with Ian on this. If you can feed Andreas special information that helps him develop these fixes, why doesn't the "inside access" conduit seem to go both ways and end up with those fixes showing up quickly in updates and new versions?
Mason Wheeler
I'm seriously annoyed at this, but on the other hand, you get that it's nice to know I've got a grip on the situation as well. Hey, I know this should work, and it does, hah! It's sort of keeps you return to the time when there were no insight you could rely on and had to know what you were doing, only sporadically.
lungic
This drives me CRAZY!!!!!!!!!
Warren P
Yeah, I'm looking at one such error right now.
Loren Pechtel
+3  A: 

No auto formatting of code! I do a lot of .NET development and some delphi as well so this is an annoyance to me.

Mike D
There's a code formatter in D2010.
Mason Wheeler
It helps but it's nowhere near as good as VS.
Loren Pechtel
And sad thing is, that I don't consider even the built-in one in VS to be any good... o_O
Robert Giesecke
I love it the way it is now. Maybe a option to auto-format code if someone want to enable it, but disabled by default.
jachguate
I use the modified build of GExperts that includes a source code formatter with Delphi 2007. It works great: http://www.dummzeuch.de/delphi/gexperts/english.html
Mick
@Masson Wheeler- The code formatter in D2010 is so buggy that it is unusable
Charles Faiga
+32  A: 

I simply want a CASE statement working with anything and not just ordinal types !

Stephane Wierzbicki
They work with enums (but they are really integers)
Gerry
Case should support enum subranges that are declared as a type. The subrange is fine so long as you declare it in the case statement so the logic is ok, it just won't take the syntax.
Loren Pechtel
More for the record: ;-) case works on any ordinal type. I guess ultimately all ordinal types are really integers, but you get the point........
Nick Hodges
Ability to **case** on a string (http://msdn.microsoft.com/en-us/library/06tc147t.aspx)
Ian Boyd
I would love this, it's just that it leads to sloppy, hard-coded strings
Petesh
There have been several times when I've wanted to use CASE on class references or **set** values. Strings, not so much. Maybe I'm just weird that way. :P
Mason Wheeler
I would hate this if it was ever changed in a way that decreases the efficiency of the current case system. If the compiler had extra code to generate a sequence of if then else statements behind the scenes, I guess that would be fine.
Warren P
@warren - I don't see why the compiler can't optimise to the current system for ordinals and something else for other cases (no pun intended)
Mike Sutton
But a 'case' statement is supposed to be more efficient for many conditions than a chain of if/else. If it is not a simple jump table then who cares? Just use if statements.
Ed Swangren
I care, for two reasons. It would be easier to write, and easier to debug.
Mason Wheeler
How about adding it to GENERICS, e.g: Case<type>
lkessler
+6  A: 

It's a small bug that was introduced a few versions back and drives me crazy. Having used Delphi for may years I became accustomed to having my Object Properties list in alphabetical order, as opposed to by groups.

When the IDE Properties Editor is changed to the 'By Name' View and scrolled, it just falls apart. This becomes quite noticeable when selecting controls on a form (when the list has to scroll) and expecting the Properties editor to display the correct object and value.

The properties don't align and focus gets all mixed up, generally requiring multiple click to rectify the situation.

Gerard
+4  A: 

Not the biggest, but a pain is the use of the same syntax for Open array parameters and dynamic arrays.

procedure TForm2.FormCreate(Sender: TObject);
var
  a : array of Integer;
begin
  setlength(a, 10);
  test(a);
end;

procedure TForm2.Test(x: array of Integer);
begin
  SetLength(X, 5); // <--- Compiler error
end;
Gerry
You need to learn Delphi language a bit more. I think if you declare a 'var-parameter' like this, you would be fine: procedure TForm2.Test(var x: array of Integer)
Warren P
@WarrenP. No. I've been using Delphi since D3. This is a case where the same syntax has differnt meanings.open array parameters can accept either dynamic or fixed arrays. To pass the parameter as a dynamnic array you need to use:`type TDynIntArray = array of Integer; procedure TForm1.Test(x: TDynIntArray);`
Gerry
My bad sorry. :-)
Warren P
+10  A: 

I upgraded to Delphi 2010 in December but really tried it just a week ago.

I haven't done much work in Delphi for years and then only in D7, which had been a crass historical touch regarding the tool set and editors I've grown accustomed to in .Net every time I used it over the recent years.

So, I did have high hopes for 2010, especially since everyone was raving about it.

Well, new project -> intellisense for units not working properly. (Wouldn't provide me with the generics.* unit names or StrUtils, .. )

I thought, well, they must have figured out how to get rid of those unnerving search paths, mustn't they? So, I created a package and an application and then told Delphi, that the exe will require the package (not as runtime pck, just the build thingy) Now, I thought I might just be able to use the units of the package in my exe without having to tinker with either search paths (yuck!) or adding the code files to the exe project as well. I had to use add the search path...

Okay, they added all this RTTI, debug visualizers, etc and I read somewhere how much improvement that gave to the debugging experience... So, simple console app, created a TDictionary<String, SomeSampleClass>, checked out the drill-down hint during debugging and did it provide me with a view of this dictionaries' data? Nope, I did get the fields of it, yes. But nothing useful. No built-in visualizers for anything useful, that I had tried. Phew!

Inspecting components is even more disillusioning. You won't even get the caption from a menuitem without typecasting or fiddeling with it...

Then, I thought: Hey, they integrated a file browser, so they would surely allow me to navigate easily to my project directory or to the file, I had open. Nope, as with almost anything, that I thought would have been the most basic user expectation from feature XYZ, I ended up, being completely disappointed.

Oh, and btw: The Delphi project explorer will still not allow to create folders and drag files around/into it to move/copy them between folders. The project managaer had always been a pet hate of mine in D7, and it didn't get much more useful in 2010 at all.

I just bought Delphi 2010, so that I might get a cheaper upgrade to native x64 or xplat in the future. So I better not use it too often until then, or I might loose interest in even those 2 prospects...

2010 is a big step forward, after all. But only compared to Delphi 7, which felt very old and dated when it was new. Compared to current IDEs like Netbeans and VS, Delphi 2010 feels a bit too cheap and unsophisticated (e.g. It still won't allow complete shortcut customization of all commands, has no highlighting for classes, interfaces, records, ..). However, I always hated the window clutter that D7 created, so this at least got much better.

Phew that was a lot more venting than I originally thought, I would end up doing... o_O

p.s.: I won't even start with "with" or the joys of single-pass compilation that requires force feeding everything in exact the right order, kinda like being a human pre-compiler.

Robert Giesecke
Man, this is a blog entry, not an answer for a minor annoyance. ;-)
Sertac Akyuz
I don't agree with everything in your post but I definitly second your comment that IntelliSense doesn't show all units. I find that very annoying
Joe Meyer
Interesting. Joe, would you mind telling me which of the annoyances of my list you don't mind or maybe even like?
Robert Giesecke
+1 for the 'human pre-compiler'
mjustin
+29  A: 

No regex support. I would love to have regex support in the IDE using a modern regex flavor and in the language without having to look for third parties components, DLLs and such.

Averroes
The IDE has supported regular expressions for many years.
Rob Kennedy
*...and in the language....*
Ian Boyd
No, Ian, the language and provided library have never supported regular expressions. That part of Averroes's complaint is valid.
Rob Kennedy
TPerlRegex saves the day. (Yes it's a third party feature, but I can't live without it)
lungic
There are many third party regex libraries. This is a library not a language issue. One may as well say that barcode scanning libraries, movie rating systems, and twitter feed readers should be built in.
Warren P
@Rob, i was pointing out the other half of the answer, i.e. "in the language". You pointed out that the IDE has regex (searching) - i thought you missed the "in the language" part.
Ian Boyd
I'm the author of TPerlRegEx. I've been having some discussions with Nick Hodges on this issue. There's hope that Delphi's regex support will be improved someday.
Jan Goyvaerts
+3  A: 

My biggest problem (and this may be related to 5 only, I don't know) is that Delphi has to unload and reload something every time I run my application from the debugger. As soon as I quit the program, I have to wait 5 to 10 seconds for Delphi to do something on disk before I can start in on the code again.

Tom
i think that's something specific to something you've setup. When i hit `Ctrl` + `F2', it kills very quickly. Perhaps you have the **Output** window visible, and all the module unloads are flying by?
Ian Boyd
Don't have that at all. Also, my app kills quickly as well, but Delphi is taking it's sweet time as apparently it had off-loaded some stuff and now has to reload it as evidenced by the memory usage.
Tom
+6  A: 

Constants are not constant enough for the compiler:

const
   SLCT = 'Large Cash Transaction';

...

const
   SAdd = 'Create a new '+SLCT+' report';
   SEdit = 'Edit a new '+SLCT+' report';
   SDeleteConfirm = 'Are you sure you wish to delete this '+SLCT+'?';

Complains that SLCT isn't a constant expression.

While:

const
    clGlassColor = $00963228;

...

const
    clGlassBorderColor = clGlassColor;

works fine. Some constants are constant enough for the constant constants.

Ian Boyd
It isn't. "const" really means "const" IOW: data section of your exe. A resource string is not that constant, provide a matching translation .dll and you'd see the difference.
Robert Giesecke
If const behaves like in pretty much every other language, then the *compiler* physically moves the value everywhere it is used. So the SLCT Variable simply doesn't exist in the compiled code, instead the desired value was "copy/pasted" everywhere. Obviously that can't work if the string cannot be determined at compile time (because it's loaded from a resource at runtime)
Michael Stum
i'll change the word "resourcestring" to "const" in my answer, Robert. The same error persists.
Ian Boyd
@Michael: i'm sure Borland can have a reason why it fails. Now they just have to fix it.
Ian Boyd
Borland? They don't even exist anymore.
Mason Wheeler
i'm sure [insert company name] can have a reason why it fails. Now they just have to fix it. Let them keep their name the same for 10 years, then i'll bother to learn it, or spell it.
Ian Boyd
it still fails if it were a const as well? Phew! That is "less than ideal"™
Robert Giesecke
It compiles if pasted into a newly created console project in D2007. (After removing ... of course)
Ulrich Gerhardt
@Mason: Borland? They **do** still exist; they just don't own Delphi any more.
Craig Young
It does seem crazy that some constants are _more constant_ than others. But here's a possible reason: Strings are reference counted, and string manipulation updates reference counts - however, that doesn't mean it's impossible for the developers to implement some 'compiler magic' to resolve it. Something worth a try... you may find shortstrings work?
Craig Young
+14  A: 

Circular References

There's no reason why you can't get rid of this problem.

Any explanation for it's existence includes, "because the compiler..."


Circular Reference Example

Customer.pas:

unit Customer

uses
    Invoice;

type
   TCustomer = class(TObject)
   public
      ...
      procedure SetMyselfFromInvoice(Invoice: TInvoice);
   end;

Invoice.pas

unit Invoice

uses 
   Customer;

type
   TInvoice = class(TObject0
   public
      ...
      procedure SetCustomer(Customer: TCustomer);
   end;

Workaround #1

Declare both types as TObject in the interface section, and do a checked cast at runtime to ensure it's what you want:

procedure GetMyselfFromInvoice(Invoice: TObject{TInvoice});
procedure SetCustomer(Customer: TObject{TCustomer});

Workaround #2

Strand one object, not making it away of the other:

   TCustomer = class(TObject)
   public
      ...
   end;

   TInvoice = class(TObject)
   public
      ...
      procedure SetCustomer(Customer: TCustomer);
      procedure UpdateCustomerFromMyself(Customer: TCustomer);

   end;

Workaround #3

Strand the other object, not making it away of the other:

   TCustomer = class(TObject)
   public
      ...
      procedure SetMyselfFromInvoice(Invoice: TInvoice);
      procedure SetInvoiceCustomer(Invoice: TInvoice);
   end;

   TInvoice = class(TObject0
   public
      ...
   end;

Workaround #4

Merge two units into one large unit:

Everything.pas:

unit Everything

type
   TInvoice = class; //forward

   TCustomer = class(TObject)
   public
      ...
      procedure SetMyselfFromInvoice(Invoice: TInvoice);
   end;


   TInvoice = class(TObject0
   public
      ...
      procedure SetCustomer(Customer: TCustomer);
   end;

Workaround #5

Use the TPersistent/Assign anti-pattern:

   TCustomer = class(TPersistent)
   public
      ...
      procedure Assign(Source: TPersistent);
   end;


   TInvoice = class(TPersistent)
   protected
      procedure AssignTo(Dest: TPersistent);
   end;

Workaround #6

Use a separate helper class:

CircularReferenceFixer.pas:

unit CircularReferenceFixer

uses
   Invoice, Customer;

type
    TCircular = class(TObject)
    public
       class procedure CopyCustomerInfoToInvoice(
            Customer: TCustomer; Invoice: TInvoice);
       class procedure SetInvoiceCustomerInfoFromCustomer(
            Customer: TCustomer; Invoice: TInvoice);
   end;
Ian Boyd
You're discounting the reason, and it's a very valid reason. A single-pass compilation structure is what allows Delphi to build large projects like the one I work on at work in *minutes* instead of *hours*, which is what it would take under C++.
Mason Wheeler
i'm curious to hear more, Mason.
Ian Boyd
Basically, single-pass compilation guarantees that your project will compile in O(N) time. The compiler never has to touch any given piece of code more than once. If you allow circular references, then the compiler ends up having to go back over units it's already compiled, and you go from a guarantee of O(N) time to a best-case of O(N) time and a worst-case of O(N^2) time.
Mason Wheeler
Plus, it's possible that changes would have to be made to the way DCUs are created and written in order to make the multiple passes work properly. If so, that would slow things down even more. (Just speculating on this point, though.)
Mason Wheeler
Multi pass compilation does not mean compile times like C++. C# is capable of resolving non-local identifiers regardless of the order in which they were declared. And it is not much slower than Delphi. (Considering that a build in C# involves more than just building, it involves running codegens like the one for edmx, xml-resources etc as well.) Single-pass should be considered some horrific memory from the dark ages, yet some poeple will cling to it as if it were something good. Kinda like stockhom syndrom for programmers...
Robert Giesecke
The fact that C# compilation times are nowhere near those of c++ doesn't make it "not much slower than Delhi". It is still much slower than Delphi. I'm not saying this is related to single/multi pass compilation, I'm just very much attached to fast compilation times. Anything that is not instantaneous is "too long" in my book.
Paul-Jan
What you are referring to, is the fact, that Delphi can link already compiled DCUs into your binary. It is not much faster than C# for a rebuild. I do not need instantaneous compilation in C#, though. Because I got ReSharper, which picks issues up without the need of compiling it first. However, the difference in speed is IMO not remotely as remarkable as to allow such a draconian burden/limitation as single-pass compilation is.
Robert Giesecke
I think that circular references being not allowed in the interface section forces you to think about your design, and prevents all kinds of nasty breakage of encapsulation. We need more limits on the knowledge of one unit's interface from anothers, not less, and less internal knowledge of one unit from another, not more. It is good to maintain interface/implementation single-pass semantics.
Warren P
In Oxygene, I used to write the interface section with the public part coming first, then protected, then assembly and private being last. Can't do that with a single-pass compiler, can you? You have to put the most uninteresting thing of a class first: the private members. Not having technology is a good thing, forces one to think about the cave he's choosing for the winter...
Robert Giesecke
No, you can write the member sections of your class in any order, with one exception: anything written at the very top, without a visibility specifier, is published by default. But you can put public before private if you want. It's just done the other way around by convention.
Mason Wheeler
@Mason: You can place the sections in any order, even have multiple sections, but properties still have to be declared _after_ the fields/methods they reference. (And for some inexplicable reason, Delphi even complains about: "Field definition not allowed after methods or properties" - but **only** if it's in the same section.)
Craig Young
@Craig: There's a reason for that too, actually. It's to keep you from declaring a field with the same name as an optional directive after the property, which would b0rk the parser. It seems really strange and arbitrary, but it makes sense if you know a little about parsers and compiler theory.
Mason Wheeler
@Warren: I tried to implement the visitor pattern in Delphi, with the domain classes and the visitor classes in different units. Very easy in C# and Java, no need to jump through hoops there. But very hard to implement in Delphi.
mjustin
I agree that disallowing circular references seems a little bit outdated nowadays. But maybe I am biased because I get this error even for code which does not have a circular reference (for which I have proof, see http://stackoverflow.com/questions/903886/incorrect-circular-reference-error - error goes away with a full build).
deepc
+31  A: 
  1. Ctrl+Click
  2. Nothing happens
  3. Goto 1
Ian Boyd
I think that this fails for the same reason that the error insight fails (see way up top of this post). Both rely on a flawed parser that works on your tiny demo apps (ergo no small test cases to report) but don't work on your big applications.
Warren P
This. You trashed my disk, killed my train of thought by blocking the GUI for seconds and you come back empty handed! At least say you're sorry :)
utku_karatas
+13  A: 

Disappearing of the "blue dots" in the code editor after an application is ran under the debugger. Have to compile again to see them again, even when the source is not modified.

This is with D2007 though, maybe it has changed.

Sertac Akyuz
Still happens to me in Delphi 2010. Also when I edit breakpoints, or set or clear breakpoints, I find the displayed code gets out of sync easily with the debugger, and I find that breakpoints "move" on me, and become useless, a lot.
Warren P
+7  A: 

Compiler will not emit symbols compatible with WinDbg, ntsd, Visual Studio, etc.

Ian Boyd
I wouldn't mind this so much if there was a cool third party debugger tool for Delphi applications. The integrated debugger improved a lot in Delphi 2010, but it's still sadly behind the times.
Warren P
Really? I'll admit I haven't worked with a lot of other debuggers, but Delphi's is *far* better than either GDB or the Visual Studio debugger. What features is it missing?
Mason Wheeler
Having compatible debug symbols would be very useful. For me, not so much for a windbg vs delphi debugger, but being able to fully use the error reports from Microsoft's winqual.
otherchirps
+12  A: 

Packages

  • Design time packages
  • Runtime packages
  • DsgnIntf.dcu not found
  • File not found: 'DesignIntf.dcu'
  • having to even install packages

Visual Studio you just have a Component in your project, and it's available on the tool pallet.

Ian Boyd
Yeah, the whole concept installing packages to get components is yet another hint of why the IDE feels so cheaply done. Why can't it infer the components from your project and present them in the IDE in the version that you have in your project?
Robert Giesecke
The experience with resolving problems with packages when two packages have had implicit declarations of units is harder than actually writing the code.
lungic
The compiler will warn in this case, and IMO, warning should be considered errors most of the time. While I don#t think that packages should be used outside the IDE, this is not really an issue of Delphi, but a user error.
Robert Giesecke
The DsgnIntf.dcu problem is actually simply an enforcement of their licensing which was routinely violated before they changed things--you were never allowed to use their code in your program but you could get away with it until they changed things.
Loren Pechtel
@Loren: Borland could have changed their licensing, so as not to make developers lives difficult. It's not like they were protecting their intellectual property - they wanted to school developers that if you compile design-time code into your final exe you're needlessly making your app bigger. i would accept larger executable sizes, if it meant not having to deal with packages.
Ian Boyd
I don't want the design time support in my runtime code base. I like the current solution.
Robert Love
+17  A: 

Resource compiler's inability to handle "Vista-style" icons.

Not that Microsoft is blameless. After two iterations of Visual Studio you still can't include a png compressed icons.

Ian Boyd
Actually you can include png compressed icons, you just can't modify them.
Billy ONeal
i meant as the "mainicon" of the application. i do add icons as RT_RCDATA already, but it would be nice to follow the UX rules and have proper app icons.
Ian Boyd
+14  A: 

Let embarcadero look what's cooking in the community and don't reinvent the wheel. If there is something nicely implemented in the community, contact the owner and use it.

Let all of the elements of Delphi be documented. Undocumented elements doesn't exist.

And I'm sorry but please hire a marketing & image company immediately.

Francis Lee
But I don't want to buy Castalia, and five other plugins. On the other hand, I find the refactoring tools and the error insight (lint) style features in the IDE so crappy that I use third party tools. In other words, sometimes a feature is well done and sometimes a new Delphi IDE feature is a weak attempt to replace a third party tool that works with one that doesn't.
Warren P
+8  A: 

I've mentioned this a few times before, but IMO properties need a little bit of work.

Properties are an abstraction that allows you to write code as if you're addressing public fields while preserving encapsulation. Since properties are supposed to look (from the outside, at least) like fields, there's no reason why you should ever be unable to pass a read/write property to a var parameter.

If read and write both point to the same internal field, it's trivial. Otherwise, read a copy of the value, pass it to the function, then take the result and write it to the property. The compiler should be able to handle this transparently in every case, instead of rejecting it.

Mason Wheeler
Your proposed implementation will give different behavior for field-backed properties and method-backed properties. Assigning a value to the parameter mid-way through the procedure will be visible outside the procedure when it's backed by a field, but the change won't be visible until the procedure returns if the property is backed by a method.
Rob Kennedy
Then, always do it with a temp variable
Robert Giesecke
@Robert: In theory it _could_ work, but the problem id that the semantic difference would be very **dangerous**! The object's state will not change until the **end** of the method.
Craig Young
@Rob: External code trying to access a value while it's being modified isn't a properties issue, it's a race condition. There are plenty of established techniques for avoiding or dealing with race conditions, and none of them involve crippling otherwise-useful language features.
Mason Wheeler
To get this to work without negative side-effect the compiler would have to call the get method set the result to a temp variable, call the function you passing the temp variable, and on result call the set method. Any other method of codegen could break existing code.
Robert Love
@Robert Love: Yeah, isn't that exactly what I said? But how would this break existing code, when no existing contains this syntax because it doesn't currently compile?
Mason Wheeler
+27  A: 

The IDE removing {$ifdef} statements and units from the unit list in the dpr file.

This is especially painful with a large dUnit "test" project I work on. The project (which I've inherited) includes a number of unit, integration and regression tests. I don't want my CI server to run the regression tests every time somebody checks in code, so I use {$ifdef}/{$endif} statement around the units. FinalBuilder then defines that conditional before building the project.

If the item is not currently {$defined}, Delphi will remove ALL of the units between the {$ifdef} and {$endif} whenever a unit is added to the project.

If the value is {$defined}, Delphi will remove the {$ifdef} and {$endif} statements from the unit list, but all of the units will be kept.

Catharz
Hmm interesting problem; perhaps there's a workaround you can try... Hopefully the IDE won't remove a {$include}; then then you can move all that code ({$idef}, {$endif} included) into a separate file that the IDE won't know to even consider fiddling with.
Craig Young
I get hit with this all the time. The two-way-tools (form designer code that rewrites your unit .pas and project .dpr interface sections) are not aware enough of IFDEFS
Warren P
Well, there are two ways for the tool to deal with that situation. "I don't know what this is. Must not be important. I'll throw it out!" Or, "I don't know what this is. Must be important! I'd better not touch it." Not sure why the Delphi team chose the wrong method...
Mason Wheeler
+5  A: 

Refactoring -> Find Unit - not really finding it many times.

Mihaela
+5  A: 

W1035 Return value of function 'xxx' might be undefined.

It isn't undefined (you can put Result:=0 on the very first line of the function and still get this warning). I believe this warning happens if the function has over a certain number of parameters and locals vars. It can be fixed with {$WARN NO_RETVAL OFF}, but still annoying. We're still using Delphi 2007, so hopefully it has been fixed in newer versions.

Mick
Turning warnings off is **NOT** a fix. Do some tests to confirm if it's related to the number of local vars and report at QC - that imo is a bad bug. Btw, if the bug is related to the number of parameters/local vars, you may want to rethink some aspects of your design that are casuing you to exceed the threshold.
Craig Young
Craig, it's a bug that's been in the product for over a decade. One more test case isn't going to help anything.
Rob Kennedy
Rob, personally I've never encountered this particular bug, so I have no idea of its exact requirements. Mick seems only vaguely aware of it; he's unsure of the limit required to induce it. "Existing for over a decade", "being well documented", and "being recorded at QC to be addressed at some point in the future" are 3 entirely different things.
Craig Young
PS: I've just tested this on a function with 100 local variables and 100 parameters. There doesn't seem to be any problem at all. If Mick is experiencing the problem on functions with > 100 Local variables and or parameters. Erm... I don't know what to say. However, I do know that many developers get compiler warnings without understanding them or why what they've done is dangerous. For example, the following produces a justifiable warning: `begin try Result := 0; except end; end;`
Craig Young
The "bug" is real but there's no good reason to fix it. It requires IIRC over 32 local variables to trigger it and good code shouldn't be doing that. There's plenty of other stuff to do first.
Loren Pechtel
Here are a couple of open QC's relating to this bug:http://qc.embarcadero.com/wc/qcmain.aspx?d=78262http://qc.embarcadero.com/wc/qcmain.aspx?d=74014As you can see, it doesn't necessarily have anything to do with the number of parameters or local variables. Craig, please stop with the patronizing responses. I'm well aware that $WARN doesn't "fix" the bug and I don't need to be lectured on my design.
Mick
@Mick: **Relax** dude; I'm trying to help! --- **You** raised the "number of parameters and locals vars"! Based on my test (mentioned above; done in both D5 and D2009), I doubt params and locals vars is the only factor. Thanks for the QC links. I'm sure you also noticed that one of them has a comment suggesting the Delphi Devs could not reproduce it. You're the one who is experiencing the problem; you're in the best position to try reduce it to a small isolated and reproducible example.
Craig Young
PS: The reason I said: "Turning warnings off is NOT a fix" is because **I agree with you**! It must be fixed! - (That's also why I up-voted your answer.)
Craig Young
I've also seen this in a function that had more than 32 branches in a case statement. The author's solution was to turn off all warnings at the project level. :(
codeelegance
+24  A: 

One of my biggest nitpicks is the help file. I almost never have a satisfying answer and need to search further. Hopefully it will get better.

Gamecat
The "delphi basics" help file would be a much better place to start than even their latest Delphi 2010 help, which is improved from 2009, but still nowhere near "good"
Warren P
Delphi help is called "Google"!
Loren Pechtel
I have given up on the Delphi help long time ago, I found it more or less useless. Instead I use http://ref.dp200x.de frequently
Joe Meyer
WinHelp / HtmlHelp ftw. Help document system ftl.
Ian Boyd
I'm so with you... Damn I miss Delphi 7 help files!
AlexV
I think the worst problem with Delphi help system is accidentally pressing F1 by a person who doesn't use this help.
too
Delphi 7 help files where really useful. The new help system is crap.
BloodySmartie
+4  A: 

And to add another one: lack of 64 bit support. I know it high is on the wishlist. But our customers need it ASAP.

Gamecat
64 bits are forbitten in this question :·)
Francis Lee
Lol, didn't saw that. But we have heavy calc applications so our customers are really waiting for it.
Gamecat
+6  A: 

I would say my biggest nitpick is the inability to follow the open source community. MySQL and PostGRE, which I've been using with c/python/perl/php for years. Regular expressions the same. Support for cvs/subversion/git. libtiff, libpng, libjpeg, libsvg, zlib and so on.

When I've started using Delphi I had no idea what most of the supported database types where. Never heard of them, and probably will never use them. While it's nice to support legacy systems, it is not so nice when you can't connect to the current application database 'cause it is using a too new tech.

Yes one can interface dll:s and so on and make them work. But I want to use them straight out of the box, like one other commented above regarding regular expressions. I want to be able to use what everyone else is using, then their problems would be my problems as well and I would feel that I could contribute, rather than inventing the wheel over and over again.

lungic
Like... where is built-in sqlite support?
deepc
+8  A: 

I keep mentioning this (it's in QC etc) and I hope that one day, someone in the IDE team will take pity on me. I'd REALLY REALLY REALLY like to be able to change the colour of the red wavy-underline error-insight marker.

I'm colourblind and struggle to see the underline on anything other than a white-background, really. With all the other customisations possible in the IDE, not being able to change this particular element is remarkably frustrating - especially because most of the time, the error-insight marker is damn useful!

I've voted up various other answers here that I agree with - I don't know if I have the latest and greatest hacks for the help files, but the help system is very frustrating in D2007 - so much useless boilerplate Microsoft stuff, auto-generated rubbish that doesn't tell you anything of any value. I've bought D2010 but not yet used it in anger so don't know if this is something they've already improved. :-)

robsoft
+4  A: 

The disappearing Syntax Check button.

I put this button on my toolbars and use it a lot. When I close a project, the button disappears. When I open a project, the button fails to reappear. Yes, I can get it back easily enough, by using the Project menu. But I use lots of test projects, I close and open them a lot, and this wretched button drives me up the wall.

Deborah Pate
I've never experienced that, but I use GExperts to assign a keyboard shortcut to that item. I used Ctrl+Shift+F9 in Delphi 5. When I upgraded to Delphi 2005, that shortcut was already assigned to another one of the "compile-like" commands, but I decided I liked my assignment better. You might consider skipping the button altogether and using a keyboard shortcut like me.
Rob Kennedy
Yes, I have always been annoyed by this bug!
Andreas Rejbrand
Agree with that. SyntaxCheckAction.Visible depends of some internal stuff effectively making it useless as Custom toolbar button
+3  A: 

When code insight for parameters pops-up, and you want to place your cursor in the statement above, code insight blocks your sight.

Like this:

Stream.Seek(0, soFromCurrent);
if FileExists( {press control+space here, and then press up}
The_Fox
+11  A: 

I hate it when I open a project form and it wants to delete components on my form because Delphi IDE doesn't care about helping me keep my packages installed and up to date.

A much better solution would be for project files to declare their dependency on a particular set of components, by name, and then having the ability to search the installed component set, and find all missing component names, and install the components that are missing.

Imagine that beside each myproject.dproj file there was a myproject.d14_pkg file, and any time that a component is added to a form in my project, the bpl and dcp files are added to that .d14_pkg file (seven zip format). Then when you open your project folder on another computer where that bpl and dcp file are missing, the project will auto-install the bpl and dcp files into their required working locations, and your form opens.

Warren P
Ditto + having to include component paths (that might vary across machines) in project files. If I install a component, I must be able to register the requirements of that component with the project that uses it, and the correct path should be added to the project. Lazarus works that way, and it is a blessing.
Marco van de Voort
+7  A: 

If I open a read-only file, and then mark it not read-only, the editor does not know about it. I have to manually right-click and uncheck the "read only in editor" box. Several other editors do this for you, like Notepad++ or Toad for Oracle (which is itself written in Delphi).

JosephStyons
or just press CTRL+S
Gerry
or F2 (save). This causes the IDE to re-check the file status and realise that it is no longer read-only.
Alistair Ward
+16  A: 

The default comments in new form classes for the public and private sections.

What a waste!! And what a terrible example of how to use comments!!

Please stopit!!

Craig Young
CodeCompletion[tm] inserting procedure declarations *above* these comments make them look even more funny
mjustin
I agree, I don't need some compiler telling me where to put my private members.
Peter Turner
You know what? I agree. I'll see about making those go away.
Nick Hodges
Are these in Delphi? Or only C++ Builder?
Warren P
A: 

A nitpick, picking on small things:

  • Borland
  • Inprise
  • CodeGear
  • Embarcadero

Pick a name and stick with it.

Ian Boyd
You're picking on names you can't even spell correctly? You probably don't know any of the background to these names. Borland/Inprise ... I agree with you: the company had a middle-aged identity crisis, and ditched in all but title that which established their initial success. CodeGear was established as a division within Borland to be sold off to the highest bidder. You can hardly claim that Embarcadero: a **different company** (and the new owners of CodeGear) falls into the category of 'not picking a name'.
Craig Young
Personally I always find it funny when someone calls them EmBorCodeDero in a blog post...
Mason Wheeler
@Craig: i chose my spelling of the last entry very carefully; and this is coming from a Delphi user since D1. @Mason: rofl
Ian Boyd
Better yet, sell the Delphi license and product to someone who gives a da** and intend to produce a worthwile product, instead of just selling off a lossy product to whoever wants it.
Lasse V. Karlsen
Craig Young
Hah! *Bore*land, i get it - cause it's Boring!
Ian Boyd
It's like Palm splitting off into Palm and PalmOne. Then renaming one of the divisions, then selling it off, then buying it back. Borland/Imprise/CodeGear/Embarcadero responded to dwindling market share by being confusing and playing hot-potato with Delphi. And when choosing whether or not to stay with Delphi as our primary development platform: the stability of the company is important. If they can keep a name for 10 years, then i'll stop making fun of their strange name. Until then, the name that sounds like a English-Spanish-Spanglish contraction will continue to get my jabs.
Ian Boyd
+5  A: 

Making class completion better in order to change parameters in a method.

Press Ctrl+shift+c and the method will be corrected in the class. (and vice versa if you are in the class, it should be corrected in the implementation.

TechnoCowboy
A: 

Improvement of the Add Unit dialog (ALT-F11), making it possible to type in a unit name, and choose wheter you want it added to the interface or the implementations uses clause.

TechnoCowboy
if I understood you correctly this is implemented in D2010 already
Joe Meyer
DDevExtensions will do this for you. Unfortunately the improved dialogs (Alt+F11, Ctrl/Shift F12) are quite slow, at least on my machine.
johnny
+6  A: 

When a extract method refactoring removes the last local variable in the "original" method, it leaves the Var statement causing a compilation error.

e.g

Procedure TSomething.DoIt;
Var
Begin
TechnoCowboy
+3  A: 

When using the Declare Field recfatoring (Shift-Crtl-D) then the field is added to the top class, not necessarily the correct class.

e.g.

type 
  T1 = Class
    Procedure P1;
  End;

  T2 = Class
    Procedure P1;
  End

Implementation

Procedure T1.P1;
Begin
End;

Procedure T2.P1;
Begin
  **** WHen Declaring a field here it will be placed in the T1 class. ****
End;
TechnoCowboy
A: 

Add shortcut key to the Evaluate/Modify debug command.

TechnoCowboy
Not sure what you mean. CTRL-F7 will pull it up...
Mason Wheeler
Sorry - i missed to find that one. Thanks :o)
TechnoCowboy
Thank you Mason! This made my day. Also +1 for the question. The right click menu doesn't show the shortcut, neither does the help. There's no easy way to find this out.
johnny
+2  A: 

Delphi as a product has been dead in the water for too long, and there's no indication that this will change any time soon.

For a while, I thought Delphi would be the best programming language for all time. For a brief period of time, in my opinion, it was. Then it lapsed. This is my "nitpick". Management took over, tried to set a new future for Delphi, and not only failed horribly, but it's like they failed with a big negative sign before it.

It all started when the biggest features of the new Delphi versions was all the new and shiny tools they bundled with it, but if you took the time to go and browse the bug-lists, the top 100 bugs, ranked by "how many are actually being affected by this bug", was still there, by and large. Things like intellisense not working, mouse-hover on variables that would go into an endless loop failing to resolve the symbol (and reading other posts here it looks like this problem hasn't been solved even today), crashing IDE, no unicode support in the component libraries (but hey, we got a shiny new data modelling tool instead! COOL!), they all cemented the feeling that they (as in, the owners of Delphi) didn't really care, instead they had about a thousand feature requests and bug reports on their todo lists, and asked the developers "now, what are the things you want to work on?" as in "now, what are the most shiny new things you want to work on, if we disregard the fact that actual people are using our product".

These days, Embarcadero (or whatever company name is currently owning the Delphi license by the time you read this), is playing catch-up. They're adding generics, and other things other platforms are doing, but they're behind. They will always be behind.

If you need to use Delphi because you already have a large code-base, stay with the Delphi version you already have.

If not, go with something else.

My "nitpick" is that Delphi was a great tool. was!

These days, Delphi is like Tony Curtis, the reptile man, way past its prime, but not exactly seeing the writing on the wall.

In the spirit of the question, let me list the minor annoyances I have with Delphi:

  • No backwards compatibility for the .DCU file format. For some versions of Delphi, they changed the version number, and nothing else. This meant that component vendors had to recompile their component libraries for a new version of Delphi for no reason whatsoever except for selling licenses.
  • Intellisense not working, simply because the compiler is one part of the product, and all the code that interprets the code for intellisense is another, separate, part of the product. Both have their own bugs, but considering that the compiler is the most important part of the entire product, where do you think most of the bugs are? Correct. Delphi 2007 had major problems with mouse-hovering over variables and procedures and would frequently either use lots of CPU, or just go into the endless clickety-click loop most Delphi-developers have come to lov^h^h^h know. Oh, you're using Delphi 2010? Tell me, is intellisense working correctly? No? Funny that...
  • A command line for the compiler that is so long that the tooltip for the output log isn't capable of showing the entire thing. Makes automating the compile step a real treat. Works wonders for everyone that likes continous integration. Or, wait...
Lasse V. Karlsen
For whoever down-voted my answer. Do you *really* disagree with me having my opinion? Because that's what this is, *an opinion*, in line with every other answer to this question. Now, you might have different priorities, like "Ooh, Delphi now has .NET support", instead of my more subtle priorities like "Ooh, it works!", but there's no way you can disagree with *me having an opionion*. After all, it is *my* opinion. Having said that, please post *why* you disagree. Otherwise you're just trolling.
Lasse V. Karlsen
I wasn't the one who downvoted it, but it's worth noting that there's a completely legitimate reason for changing the DCU file format number. If any major features get added that change important base classes like TObject, TComponent or TControl, then even if the DCU format itself remains unchanged, the DCU *data* will be incompatible and need to be rebuilt. They managed to avert this in the D2006 -> D2007 update by jumping through some very strange technical hoops, but in most other updates they didn't bother.
Mason Wheeler
They did this by using the same compiler. And the "very strange technical hoops" were something on about the scale of a carpet-edge. IOW: Just reusing techs from before like defined published properties and classhelpers to get new properties into the designer. They wouldn't go through any lengths to ensure compat. between version, they just didn't want to write a new compiler. Probably because they were in the middle of the generics transistion and what they got for a compiler was a bloody mess at that time.
Robert Giesecke
"A command line for the compiler that is so long": you can use MSBuild since Delphi 2007 for continous integration, so you won't have to deal with the command line parameters.
Giel
Lasse, voting an answer down is not a personal attack against you. It means the voter didn't consider this response to be a useful answer to the question. You used this question as an opportunity to get on your soap box and rant about how awful the entire Delphi operation is. That's not a nitpick, and given the attitude expressed in your answer, it's definitely not just a minor annoyance for you.
Rob Kennedy
Point well taken.
Lasse V. Karlsen
+2  A: 

Forward declarations.

This is really a rebuttal on the previous post about circular references.

I USED to gripe about it's inability to handle circular references but I've come to realize that they most likely reflect a design deficiency--when you find yourself in an A uses B, B uses A situation the most likely situation is that they should be both siblings under C.

The real problem is a lack of long range forward references. Every beef I've had about a circular reference would be solved if I could declare the interface and implementation in entirely separate units.

It wouldn't break the single-pass nature of the compiler and I don't think it would be that hard to implement. Add a keyword Delayed before Implementation--if the compiler finds it it stops compiling that file and goes on with whatever else it wanted to do. Only once everything else is done does it go back and finish compiling anything that was left behind. The compiler has everything it needs in the interface, it can go on and come back to finish the job.

Loren Pechtel
I don't quite understand how that would change things. The compiler does something similar already. Your idea almost makes me wonder if you know about separate **uses** clauses for the interface and implementation sections?
Mason Wheeler
"delayed" is already a keyword that is used for late binding external (DLL) functions.
Andreas Hausladen
Separate uses clauses reduce the circular reference problem but they don't eliminate it.
Loren Pechtel
A TCustomer class knows to create itself from a TInvoice, and a TInvoice knows how to create itself from a TCustomer. If you tried to split TCustomer and TInvoice into separate until you get a circular reference. The hack is to have the method `TCustomer.FromInvoice(Invoice: TObject)` and `TInvoice.FromCustomer(Customer: TObject)`. Another hack is to use the TPersistent/Assign pattern. But the point still remains: unavoidable circular reference.
Ian Boyd
You can put both the tCustomer and tInvoice in the same unit and use ordinary forwards here. Where you get stuck is when they are forms and can't be put in the same unit.
Loren Pechtel
@Loren: Or you want them in separate units
Ian Boyd
+1  A: 

Code templates

A nice idea in theory but I've about decided to turn them off because they are so stupid in how they work. When you're in the interface section or a class declaration and type Procedure or Function it puts the Begin End in there!

Loren Pechtel
You don't have to turn them /all/ off. You can edit templates to make them manual if you want to.
Nick Hodges
+1  A: 

Not being able to embed variables in strings and have them expanded. I never knew I was missing this until I learnt php. It would be so much easier than using format.

For those unfamiliar with PHP - this is possible.

$Message = 'Go to the Zoo';

$Full = "I said '$Message'";

echo $Full;

will output

"I said 'Go to the Zoo'

In Delphi (and virtually every other if not every other compiled language) this would require either string concatination (which is a pain) or use of the format function (which is also a pain).

It would be a nice to have.

Toby Allen
Could you edit your answer to give an example? i'd be curious to know what i'm missing.
Ian Boyd
There is a huge difference between compiled and interpreted languages.This example you have relies on the fact that PHP is an interpreter.If you do this often enough that it's annoying, then write a function for it!
rep_movsd
+8  A: 

An array defined with no defined boundaries but an initializer containing n elements such as

Foo array [] of int = {0, 2, 3, 4};

should compile and default to [0..(n-1)]

And by extension,

Foo array [5..] of int = {0, 2, 3, 4};

should default to [5..8]

filofel
+2  A: 

I don't think there's been much improvement in the base DataSet components, and they could make some great time-saving improvements with relatively little work, I think.

For instance, why do I have to open up a TStrings editor to check the SQL inside a Query component? Why can't I just move my mouse over it and have it displayed as a hint - along with any defined parameters, while you're at it?

Come to think of it, if I move my mouse over any TDataSet, TDataSetProvider or TDataSource component, why not highlight in some subtle way the other components that are linked to it?

RichardS
A: 

Another nitpick:

Why do we still have inadequate handling of file modes?

Why can't we append nonexistent text files? Why can't we reset nonexistent binary files?

Sure, we would need new names to avoid breaking old code but that wouldn't be that hard. Just let me Open any file!

Loren Pechtel
+2  A: 

Pressing F7 in the debugger for a Step Into, causing Delphi to go to 100% cpu and after a minute or so ending up in totally unexpected code or an unstoppable sequence of Access Violations, which only can be stopped by resetting the program. Most of the time caused because there is no source file to step into.

This is on Delphi 7, maybe it's fixed in later versions, but it is certainly very annoying.

Edit: Andreas Hausladen fixed this issue with the release of Delphi Speedup 2.8. Also, the Access Violations were caused by DEP (Data excuction prevention). Turning it off will end the Access Violation problem.

The_Fox
+18  A: 

I hate that control-clicking something doesn't take you to its declaration when debugging.

Catharz
+6  A: 

One of my biggest nitpicks is the lack of simple Delphi examples in the help file.

Charles Faiga
+3  A: 

If I add a public property to a class that has a strict private and public section and press ctrl+shift+c bds 2006 messes up my class. I get an extra private section for the property setter and variable. This often leads to code that no longer compile.

Does anybody know the reason why private isn't really private when it comes to delphi? Why are components on a form visible to other forms? One of the reasons it annoys me is that it clutters the code completion list. If I were to mention the others this quickly becomes a rant.

Where I work we have all projects in one project group, there are about ten of them. Building them all eats a gig of memory and delphi dies a violent death, at least on my machine. Why, I have 4 gigs of memory?

johnny
Strict private and shift+ctrl+c simply don't work together. It always adds an empty published section and declares e.g. property fields in a new private section (as you wrote). And then I have to clean it up manually. Previously it was a no brainer to use class completion, now it is discouraging to know upfront that you have to clean up the mess afterwards...
deepc
+1  A: 

My daily annoyance is the IDE editor's Ctrl+Tab behaviour. It just cycles through the tabs, a real pain if you have multiple files open, and want to toggle between a specific two. You have to manually drag-rearrange the tabs, then use Ctrl+Tab and Ctrl+Shift+Tab. It should be that Ctrl+Tab, Ctrl+Tab toggels between the last two viewed, and Ctrl+Tab+Tab continues the cycle. Have a look at Windows (Alt+Tab), VS, Firefox, etc.

avenmore
Try pressing Ctrl+Alt+F12 - this will open the dropdown menu on the upper-right part of the editor, from which you can select the unit just by typing it's first few letters and pressing enter. Look ma! No mouse needed! ;-)
PatrickvL
The described behaviour is highly counter-intuitive to me. In past Eclipse version this was the only way to switch tabs by keyboard and it was really bad. Think about it: you see a tab you want to switch to (e.g. 3 tabs right). What is easier: 3 times ctrl+tab, or having to remember when you accessed that tab the last time / keep pressing ctrl+tab until you finally get to it?
deepc
+2  A: 

By biggest nitpick about Delphi 2010 is the change to Find in the text editor. I agree that it's a bit nicer and a more modern way of working, but it completely throws me every time. I think its because the OK button on the find dialog isn't in my face, and I have to go looking for the options. It would be great if you could just hit F3 from within the search box, to initiate the find (as that's usually what you press next)

Homer
+4  A: 

SOAP support is not up to par, partucularly with namespaces. SoapUI is the de-facto tool used in many enterprises to test/mock/develop soap services. If your XML request (coming out of Delphi) doesn't work, but output from SoapUI does, guess what? It's your problem. I have recently done a large project that involved dozens of StringReplace calls to modify the serialized object so that I could copy/paste into SoapUI, have it validate, and be accepted by the server. Not cool. If Delphi were able to serialize the XML in the same manner as SoapUI (with declared namespaces at the top, and no in-line namespaces), then that would be a HUGE benefit to anyone doing webservices in a mixed (.net, java, delphi) environment, where the only common reference is SoapUI. I'm venting here because I just got done sharing my code with another guy who has the same issue... http://stackoverflow.com/questions/2473051/delphi-soap-envelope-and-wcf

Chris Thornton
We hit exactly this issue. The idea was to have a WCF web service written in C# with the client in Delphi. Due to the poor SOAP support in Delphi we ended up doing the client in C# as well.
Pauk
+19  A: 

Not having UNDO in the forms editor. Can't believe nobody else mentioned that!

You play a bit with the controls in the forms editor, move them here, move them there, then click undo, then move them elsewhere... oooops... did I say "undo"? What's that? Not something you'll use in Delph Forms Editor.

I vote for UNDO to be removed from Notepad, Visual Studio and Photoshop as well. If you screw up your form, just make it again from scratch. That's the way to design forms in 21st century.

Zex
+1 This is number one for me. Especailly when I the IDE decides to randomly remove a property you need
Willbill
+9  A: 

When debugging, I use the Evaluate/Modify (Ctrl+F7) dialog a lot, and would like to see a simple extension : Actual type evaluation.

Let me explain; Up until now, when evaluating a variable of some class-type, I have to play out this scenario:

After I invoke the dialog with Ctrl+F7, I have to :

  • Focus the 'Expression' edit box (either by mouse, or with Alt+E)
  • Append ".ClassType" to the variable name
  • Press 'Evaluate' (either by mouse, or with Alt+V)
  • Focus the 'Result' box (either my mouse, or with Alt+R)
  • Select and copy the shown type into the clipboard (either my mouse, or with Ctrl+C)
  • Focus the 'Expression' edit box again (you'll know how by now)
  • Paste that before the variable (Ctrl+V)
  • Put parenthesis around the variable and remove the ".ClassType" part again

Only after these (easily automated) steps, I get to see the actual type in all it's detailed glory. And that with a mere 26 keystrokes! (If I counted them right, I could be off a few) ;-)

You'll understand this has become very tedious, and it would be my #1 improvement to Delphi.

PS: The same functionality should be added to the watches, local variable and object-inspector views too.

PatrickvL
Yeah, that would relieve us of some tedious work! +1
Ulrich Gerhardt
+2  A: 

Sometimes when I undo a change in the code editor (Ctrl+Z), the text in the editor gets corrupted. A lot of strange characters appear, and you simply have to close the file (maybe even the entire RAD Studio) and reopen the last saved version of the file.

Andreas Rejbrand
What version are you on, and do you have the latest patch? I'm not completely sure, but I think that was a glitch specific to early releases of Delphi 2010 that was fixed in an update.
Mason Wheeler
@Mason Wheeler: OK, I use Delphi 2009.
Andreas Rejbrand
@Mason Wheeler: I have the latest updates to D2009, and it happened to me earlier this day...
Andreas Rejbrand
This appened several times to me too over the past week, lost all my code changes. Delphi 2009.
mjustin
A: 

The new resource-compiler still generates loads of .tmp files when the .rc files are read from a readonly folder.

After a few days of building the various branches I work on, I have to delete 30.000+ .tmp files. That in itself is not a big problem, but the fact that a collision in .tmp filenames causes the build to fail, is!

Mind you, I have about 20 branches of the same codebase on my machine; This codebase consists of 51 projects, build from 1300+ .pas files, good for about 15 MB of code alone. The culprit are the measly 24 .rc files which invoke the resource compiler, which generates not-so-temporary .tmp files, which on their behalf break the build when a .tmp file can't be overwritten. (They seem to inherit the readonly flag from their parent folder).

PatrickvL
+3  A: 

Couple of small things on code completion.

We work with interfaces a lot and it would be good to have code completion in these 2 scenarios:

Adding properties to interfaces

If I write the following code:

IMyInterface = interface(IInterface)
    property MyProp: Integer;
end

It would be good to hit Ctrl+shift+c and the IDE would write the declarations for the getter and setter methods.

Implementing an interface in a class

Similar to VS.net if I say a class implements an interface it would be good to automatically get the IDE to pull in all the methods and properties from the interface in to the class to save my copy and pasting them. (I think you press TAB to do this in VS.net)

Jamie
+2  A: 

The horizontal scrollbar on the Project Manager disappeared in D 2010!

Piet
+4  A: 

All controls on a form should be private by default.

Controls on a Delphi form always have published visibility, and this can not be changed, because streaming from/to DFM requires it. But IMHO it violates the Encapsulation / 'Information Hiding' principle, and also floods us with information: if a developer types Form1., the IDE will present her a list with all controls, when she only wants to see one (or two) public methods to show and execute the form.

mjustin
+1! The amount of abuse I've seen from this over the years is epic.
afrazier
+1  A: 

I still think that when there is a new Delphi version, that we shouldn't have to buy new components. If there isn't any major change (like Unicode), components should work from version to version. I know it will be detrimental to the third-party component vendors, but now they'll have to improve the components from time to time, instead of just updating the same old component so that it will work with the new version of Delphi.

Phillip Woon
Most of the time, old components do work with new versions. You just have to recompile them (you *did* get the source, didn't you?) and maybe update an include file or two with new version definitions, and you're done.
Mason Wheeler
A: 

Since it hasn't been mentioned among the rest of these very pertinant issues, I wish the forms editor wasn't so clueless.

There are click browsing bugs aplenty - click on anything in the structure panel while editing a form and it takes a quantum leap to someting miles away in your list. You have to scroll back to what you wanted to click on originally and click it again. Annoying!

Drop a component on your form and it takes a quantum leap into another groupbox or frame or whatever, often hiding behind a bunch of your other components. To fix it you have to go to the structure panel, find your new component, click on it (go to paragraph 1) bang your head, and then put it where you dropped it in the first place.

Try getting components to align in the form editor? Snap to grid doesn't snap, alignment anchors will try to align to something half way across the form instead of the component that is ten pixels away - it's like wrestling a Russian bear. Headhunt some people from Adobe if you have to, Embarcadero, but just make it work intelligently!

It's not so bad if you're doing simple things, but my apps are generally for control systems and I've got frames with dozens upon dozens of components - indicators, buttons, controls, readouts. The amount of time I waste trying to make it look like something other than a kindergarten seashell mosaic or impressionist Picasso is madenning. Typically it means manually typing in origin coordinates for every single component.

Justin
A: 

Number of elements differs from declaration.

Just tell me how many elements to put in the array!

Peter Turner
@Peter: Better still, just allow "array of" declarations of array consts and let the compiler count the size.
Mason Wheeler
@Mason Wheeler: And then you get index out of bounds exceptions because you miscounted and you are absolutely sure it has 10 items... Then you count again and discover you have 9 :)
The_Fox
@The_Fox: if is a loop, just count from Low(array) to High(array)
Fabricio Araujo
@Mason, why do I get the feeling I'm searching in vain for that option in Delphi 7?
Peter Turner
@Peter: Sorry. I mean, the language ought to allow you to do that. (But it doesn't.)
Mason Wheeler