-
Content Count
1111 -
Joined
-
Last visited
-
Days Won
96
Everything posted by Dalija Prasnikar
-
Anything from JetBrains... I am not saying that Delphi is stuck in the Stone Age... but it is lagging behind in some areas.
-
Can not install Delphi Community Edition 11.2
Dalija Prasnikar replied to Kurt G's topic in General Help
DO NOT DELETE THIS FOLDER It contains license information. If there is a reason for removing or editing some license, it should be done through license manager. If it really needs to be deleted, then copy it to some place first, so you can put it back just in case. -
Skia4Delphi_VCL sample project raises an exception
Dalija Prasnikar replied to Ralf7's topic in General Help
It would help if you would provide more information about the exception. The demo works fine for me. -
Because conditional jump requires more logic in compiler than simple single jump. Yes, there are other more complicated things in the compiler, that is besides the point. We are talking about goto command which is rarely used and often even considered obsolete. While it has its use cases, extending the goto functionality is really the last thing we need. In that context how complicated feature might be matters. That is why I (erroneously) opened discussion with how many jumps it needs and this could have been a reason why using goto to jump outside try...finally was not implemented.
-
The jump to finally happens behind that call. If you use Continue, the jump will become more obvious. File a QP report if you think it is important to have it. You can use any code you wish. Like I have already said, I was wrong that there is only single jump involved for the Break and Continue.
-
You are right, I forgot that there could be code in the loop after the finally, which requires additional jump.
-
No, it is not the same functionality. Break and Continue will just make single unconditional jump to the finally, while goto would require two jumps, one of them conditional. It is far from being the same.
-
Locking an Object
Dalija Prasnikar replied to fastbike's topic in Algorithms, Data Structures and Class Design
You cannot use TMonitor in such scenario as you don't always have live instance to call upon. Also there is a simpler code than your example commonly used for double checked locking. However, that pattern assumes that calling the constructor is all that is needed to fully initialize the object. Only if there is additional initialization needed after construction, there is a need for temporary object. So this code would look like: function GetMyObject: TMyObject; begin if FMyObject = nil then begin FLock.Enter; try if FMyObject = nil then FMyObject := TMyObject.Create; finally FLock.Leave; end; end; Result := FMyObject; end; or with additional initialization function GetMyObject: TMyObject; var TempMyObject: TMyObject; begin if FMyObject = nil then begin FLock.Enter; try if FMyObject = nil then begin TempMyObject := TMyObject.Create; // additional initialization for TempMyObject FMyObject := TempMyObject; end; finally FLock.Leave; end; end; Result := FMyObject; end; -
Are there current issues with QualityPortal?
Dalija Prasnikar replied to Rollo62's topic in Software Testing and Quality Assurance
No, it is not only you. I cannot log in either. AFAIK, the IT has been notified. -
how can I effectively destroy a form that contains a TEdgeBrowser while it is loading?
Dalija Prasnikar replied to a topic in VCL
Can you please show the minimal working example of your code that you have problem with. It is very hard to follow explanations of the code. We need to see exact code, to be able to help and propose solution. -
Do local variables have a cost?
Dalija Prasnikar replied to Nigel Thomas's topic in Algorithms, Data Structures and Class Design
If Foo is reference counted type, then GetFoo will require hidden reference created to properly initialize reference counting, regardless of how DoSomethingWithFoo is declared. If it is declared as const that only means there will be no additional reference counting involved (_IntfCopy and _IntfClear) calls. Hidden reference is equivalent of the explicitly declared local variable. It is created when there is a need for holding a reference to something for calling _IntfCopy and _IntfClear methods. If there is already a reference (when passing parameter to some procedure where parameter is not declared as const) then there will be no hidden reference because _IntfCopy and _IntfClear can be called on that reference directly. Same principle applies not only for interface , but also for other reference counted types like strings and dynamic arrays, the only difference is in particular reference counting methods that will be called. -
Do local variables have a cost?
Dalija Prasnikar replied to Nigel Thomas's topic in Algorithms, Data Structures and Class Design
If it requires reference counting, then there will be hidden reference created behind the scenes and the actual generated code will be the same in both cases. -
Ahh... that is a slightly different case... but, yes, it can be a nightmarish scenario. I had some of my own libraries with messed extensions and it took me a while to realize what is wrong.
-
Well, 280 is a version 11, and Delphi 12 is 290 so Delphi 12 will definitely not like such bpl.
-
This work on modernization is the foundation as potential future support for Android and iOS requires more modern toolchain.
-
There are no implications for Delphi. this is solely C++ Builder issue. AFAIK, C++ Builder side is going through a major upgrade https://docwiki.embarcadero.com/RADStudio/Athens/e/index.php/BCC64X and this work had a priority over supporting iOS and Android (which never had 64-bit compiler required for distribution through Google Play Store)
-
Delphi 12 supports those platforms. It is probably left over text from version 11, where You needed at least 11.3 to run applications on Android 13. I haven't tested it on iOS, but Delphi 12 definitely supports Android 13, including uploading on Google Play.
-
Is it a problem if I create more threads than host CPU has ?
Dalija Prasnikar replied to William23668's topic in General Help
CPU is a finite resource. You will not get more of it, by throwing in more threads. If there are more threads than CPU cores, those threads will compete with each other for CPU time, and switching between threads also costs some CPU time. So after you overload the CPU, more threads you add the slower it will work. Only if threads are doing some I/O bound work, then you can have more such threads than CPU cores and possibly whatever you are doing can finish in less time. In other words if the thread spends most of the time waiting for some slow I/O operation, then such thread will not fully utilize CPU core and other threads can do useful work in the meantime on that core. However, even in I/O bound operations, there are limitations and if those threads are competing for the same resources, then again, the whole process will run slower. Imagine that CPU core is a shovel and threads are workers. In CPU bound work workers need to dig some ground. If you have same amount of shovels as workers than each worker will use the shovel all the time without having to give it up and it will be able to do the digging at full speed. If you have more workers than shovels, then workers will compete for that shovel. And it will not be in a way that some workers will use the shovel all the time and others will do nothing, but each worker will get very short time to use the shovel, maybe only taking one or two loads, and then it will have to give the shovel to the other worker that is waiting. But transferring shovel from one worker to another takes time, and at the end everything will run slower than if you have only one worker per shovel. On the other hand, if the worker also needs to use a pickaxe, then while worker is using the pickaxe, he does not need the shovel, and someone else can use it until the worker is done with the pickaxe. This is example of I/O bound work, where pickaxe is some I/O resource (network, disk...). Again, if you have more workers that compete for the pickaxes, the whole thing will work slower than single worker using that pickaxe. Now, this is simplified example. When it comes to your application running, it is not just your application that uses the CPU cores, but OS and other processes and applications are also using them, so you also need to take those into account. Now finding the right balance for the actual work can be hard and will depend on other parameters, and usually you don't have to optimize that much. But in simple terms, you definitely don't want to have more threads working at the same time than CPU cores, if those threads are doing CPU bound work. Commonly using as much threads as CPU cores or one less, will do - you can experiment with that, but again this is something worth pursuing for most applications. If you are writing something that will run on specific hardware then you can more easily optimize, but if you need to make it work across different ones, then good optimization for one may be a bad optimization for another. -
The first example is the correct one. The second one is not, as TThread.Queue will run after lStrings instance is being destroyed. Also it is extremely important that you pass nil to the TThread.Queue like you did because passing the current thread instance TThread.Queue(TThread.CurrentThread, would remove queued procedure when the thread has finished running and if that happens before queued code had the chance to run there would be a memory leak. This is less of a problem with tasks, as their threads are reused, although theoretically, such situation can still happen. But if you replace TTask with anonymous or custom thread then such situation is more likely to happen, especially if there are no more code in a thread after calling Queue that could delay its destruction. However, the second example would also work if you would use TThread.Synchronize instead of Queue ad Synchronize is blocking call and Free will be executed only after code inside Synchronize is executed.
-
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Dalija Prasnikar replied to Yaron's topic in General Help
Well, that could be a problem if those components are not supported on newer Delphi versions. I don't know because I am not familiar with them. If you do need to replace those components you can make substitute components that will allow loading of the project and will give you if not the same then similar functionality. List all the components you need and find appropriate functional replacement from the Delphi version you plan to upgrade. Then create package your own set of components that will have the same names as TNT components and inherit from appropriate components in new Delphi. Then add all the properties they have that might be different. You will also need to hook up and implement appropriate functionality behind those properties, unless they are functionally unnecessary and you just need to have dummy property to allow loading of a project in new Delphi. This set of components and controls will allow you to open the project in new Delphi version and use those as replacement for TNT components without the need to change form dfm files. It is important to make all those preparations on small test project so that you have everything working properly before you move your actual project. Unicode Delphi also has a WideString, so in theory you could keep using it, but if you are using WideString to interact with TNT components you may need to replace those to generic string type in new Delphi instead of introducing WideString properties to your TNT replacement components. -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Dalija Prasnikar replied to Yaron's topic in General Help
Like @Remy Lebeau said, start by using UTF8String for strings that hold UTF-8 data. It exists in Delphi 7, too. And doing that will make your transition to Unicode Delphi smoother. You will also be able to more easily verify that you haven't broken anything while doing changes in Delphi 7. This should be your starting point. Another thing you can do is make a short demo application where you will use the most common string handling patterns from your code and then you can transform and move that code to Unicode Delphi. If something goes wrong in that small demo you will be able to more easily understand what you need to do and how. -
I need advice on converting a 500k lines 32bit Delphi 7 application to 64bit
Dalija Prasnikar replied to Yaron's topic in General Help
Don't do that. This is the wrong approach. Just follow the hints from compiler. It will tell you where you need to do something about string conversion. For most of the code you will not need to change anything regarding strings. And if you do blind search and replace you will create more issues in your code than you will solve potential problems. -
Using inline variables inside loops
Dalija Prasnikar replied to havrlisan's topic in RTL and Delphi Object Pascal
This kind of behavior would be the best. -
Using inline variables inside loops
Dalija Prasnikar replied to havrlisan's topic in RTL and Delphi Object Pascal
This is expected behavior. There is only single address behind inline variable declaration, not multiple ones. Also captured variables are not stored in the stack, but on a heap. Anonymous methods are basically defined as interfaces with a single method - Invoke - implemented by a hidden reference counted class, and captured variables are stored as fields of that class. When an anonymous method is accessed, an instance of that class is constructed behind the scenes, and it is kept alive through reference counting for as long as is required by the anonymous method it wraps. Because you have a loop you will only see the last value in that captured LKey variable because there is only one anonymous method instance created which you are adding to the list again and again with only one captured LKey field. -
Load of JPG fails - only on MacOS Sonoma running on Intel!
Dalija Prasnikar replied to Hans♫'s topic in Cross-platform
This is a known issue. Reported as https://quality.embarcadero.com/browse/RSP-40939 The issue is caused by some change on OS level which trashes the FPU. Above report contains a patch containing fpu_init2 procedure which needs to be called after loading from stream. The patch seems to solve the issue in particular scenario for the reporter.