Michael Nicht - WikiCommons

Preparing next release of kbmMW, I merged in the latest versions of the socket library which I have commercially licensed for your coding pleasure 🙂

One part of the code that has changed since last version is the OpenSSL support code. A number of IFDEF’s and IF statements has been added along with some more definitions, to be able to handle static vs non static OpenSSL library support. All in all very well!

The problem however is that I could simply not compile that particular unit. It constantly complained about this part:

The compile error was:

[dcc32 Error] kbmMWOpenSSL.pas(692): E2029 ',' or ':' expected but identifier 'CRYPTO_THREADID_set_callback' found

After a while I thought… ok… it could be because somehow CRYPTO_THREADID_set_callback etc. was already defined elsewhere… which would be a bit weird as the developer on this project usually is very capable and thorough, so I wouldn’t expect such a bug to slip thru the testing before the code was committed.

But nevertheless…. that is the only thing that would explain the problem. As the CRYPTO_THREADID_set_callback etc. values are defined 2 times… one for when the OpenSSL library is to be loaded dynamically and one for when its to be handled as a static library, I searched high and lo. No apparent bugs could be found.

So was the compiler somehow getting confused about when the __SSL_STATIC__ definition was active and when it was not? I tried many things… even to make a __SSL_DYNAMIC__ definition to explicitely ensure that the __SSL_STATIC__ definition was not in use at that particular area…. all to no avail.

Ok…. so could it be that the CRYPTO_THREADID_set_callback etc. values are defined elsewhere, and that interferes with the compilation?…. Searching thru all of the Delphi source code, I found that yes… Indy does define it too. But I dont include Indy units in this unit…. so it shouldn’t interfere???

Well… to be on the safe side… rename all CRYPTO_THREADID_*  in my code to be called kbmMW_CRYPTO_THREADID_*  instead. For sure there wont be code elsewhere that will have conflicting names.

Now problem should be solved… so Compile…. argh…. same problem… ok… maybe some reminiscence from the previous compiles… close IDE, restart, Build All….. Damned…. problem still there!

In desperation I moved the first line out before the $IF statement… and voila…. no error on that line…. but the next line within the $IF statement now errors.

Weird… then I commented the comment. Making it look like this:

The problem disappeared. It could compile. Ignore the bogus squigly on the IFEND.

So the comment is the problem.

If I removed the spaces before the original comment, the problem also disappeared.

It turns out that the last comment line had non breaking Unicode spaces instead of regular spaces. UTF-8 character $C2 $A0 or Unicode character $00A0.

So it seems that despite the editor being Unicode capable, enabling variable names and comments in any language you decide to use, it will not accept Unicode spaces except for the regular old $20 space character.

Replacing the non breaking spaces with regular spaces made the unit compile without problems. I was using Delphi D10.2 Update 3 during this investigation.

I however must assume that the code did compile in the IDE of the original developer…. The developer might have used Lazarus or some other IDE during writing and compiling his changes.

The lesson learned is that for Delphi, a space is not just a space. A space must be an ANSI space to avoid problems.



2 thoughts on “Delphi revelations #2 – Space characters are not just space characters”
  1. Non-breaking spaces wreak havoc in JavaScript, too. I think it happens sometimes when people copy code from web sites.

    I have a static checker that runs as part of a build process to pick these up. I think I’ll need to check my Delphi files, too.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.