Jump to content

C++ proposition


Jief_Machak
 Share

823 posts in this topic

Recommended Posts

Quote

 Could you send me the command line to start Qemu with the EFI bios. When I do it, I have no display : QEMU window is there, but stays black.

 

-drive if=pflash,format=raw,file=

 

EDIT: Don't know why it didn't quote you...

Edited by apianti
Link to comment
Share on other sites

well what else are you using? I do this

qemu-system-x86_64 -m 8G -smp cpus=1,cores=4,maxcpus=4 -vga std -boot order=dc,menu=on,splash-time=2000 -drive if=pflash,format=raw,readonly,file=FIRMWAREPATH

where FIRMWAREPATH is where ever your firmware file is.

Link to comment
Share on other sites

7 hours ago, Slice said:

EDK2 is full of unused codes, checks and asserts because of this.

C is very bad language while it is universal and easy to compile. 

Clover sources has huge amount of checks and type casting and anyway it still has bugs origin from bad programming style inflicted by C language. Rewriting codes to C++ causes more compact codes with more internal proofs.

 

Now I'm curious too... in what ways is it more reliable? The only things I could think of right now are

1) heap memory chunk sizes cannot be gotten wrong (new vs malloc)

2) references (you partially avoid them even)

3) possibly reference counting?

 

ASSERTs in edk2 are mostly caller contract stuff, you very well need that with C++ too. What kind of checks can you avoid now?

You both mentioned templates, but except for some rare good cases, I only know them as bloat.

 

As for my 1) to 3), they are most minor to me, especially looking at what else could be done with the time spent to rewrite huge chunks of code.

Link to comment
Share on other sites

@Download-Fritz I definitely agree about templates, they can be a nightmare. But few can help avoiding cast. Casts are always a big big source a trouble as they defeat any compile checks. We have 2 "collections", probably won't need more than that. But for these ones, it's nicer then just a non-templated object that would have to take a void* as parameter et and return value of operator [].

 

I love references.

 

Virtual methods also allow to avoid casts. We use that for menu_item. Later, we can also put some behaviour in these menu items objets which will avoid recurring tests like is it a checkbox, or is it blabla to be able paint them, for example.

 

I tend to use almost never the new operator, except to create an object that I'm putting immediately in the ArrayObj who will take care of freeing it. If I design well, I never ever call delete operator myself, which also means I never forgot and no memory leaks.

 

Also, but we talk about that, some "sugar" in code writing : we can now avoid to 

  1) declare a CHAR16*

  2) allocate it

  3)remember to free it after use. With return in middle of function, it's sometime easy to forget.

Now, we just declare :

  XStringW(L"what ever");

  we use it... and done.

It doesn't looks like a huge improvement, and it's not. But wouldn't I have it ?

 

Story short, some simple C++ mechanisms allow to avoid pointer and casts. They are the 2 major sources of problems.

 

I know there is a price to pay in performance. But I also know that the difference between a function and a non-virtual method is just one parameter more (this). How many milli-seconds is that ? The difference with a virtual method is a pointer loading (vtable) + one parameter. Doesn't seems huge to me (of course @apianti will tell I'm scientifically wrong, etc. :-)

I know the code will be so much nicer to read that it's worth it. If some people are against a C++ over C because of performance, why are they against C over assembler. For the same reason he prefer C over assembler, I prefer C++ over C. Knowing that I can still do what C can do, why would I prefer less tools for a project ?

  • Like 1
Link to comment
Share on other sites

I can write code in c++ that can defeat type checking, it's called reinterpret_cast. All boot memory is free'd at exit boot services so not sure where there's going to be leaks, but probably issues with memory during usage. You could create a formatted string in pretty much the same way in c.... It's just a different mechanism that equates to the same code eventually with more overhead. You are basically using the same c code but wrapping it in object oriented behavior, so you are only adding overhead. Pretty much everything you said was incorrect, so I see this is clearly only because you want to use c++, not because there is an actual benefit to using it.

  • Haha 1
Link to comment
Share on other sites

32 minutes ago, Jief_Machak said:

I didn't see your commit until 5 minutes ago... Next time tell me on message if you want me to have a look.

Do I still need to have a look ? 

No yet. I will do other things.

Link to comment
Share on other sites

@Slice and @Others : IMPORTANT : read carefully for refactoring a CHAR16* or CHAR8* in XStringW

 

I have temporarily removed the assignment and copy ctor from CHAR16* from XStringW

 

Reason is with them, something like below would work :

  Entry->Title = EfiStrDuplicate(FullTitle);

  SubEntry->Title = PoolPrint(L"Run %s", FileName);

It's a leak because we XStringW doesn't free the CHAR16 argument after assignment (and cannot do).

To be able to catch them more easily, I removed the assignment and ctor, so the above won't compile. The only thing is, now, if we want to assign a value to an XStringW, we can't do str = "litteral" or L"litteral. I created a method takeValueFrom(). For now let's use str.takeValueFrom("litteral").

We can't do either XStringW str("litteral") or XStringW str(L"litteral"). I created a XStringWP (like a short for XStringW from Pointer). Because it's a subclass, just declare XStringWP("litteral") or XStringWP(L"litteral") and use it as a XStringW.

Link to comment
Share on other sites

18 hours ago, Jief_Machak said:

@Slice and @Others : IMPORTANT : read carefully for refactoring a CHAR16* or CHAR8* in XStringW

 

I have temporarily removed the assignment and copy ctor from CHAR16* from XStringW

 

Reason is with them, something like below would work :

  Entry->Title = EfiStrDuplicate(FullTitle);

  SubEntry->Title = PoolPrint(L"Run %s", FileName);

It's a leak because we XStringW doesn't free the CHAR16 argument after assignment (and cannot do).

To be able to catch them more easily, I removed the assignment and ctor, so the above won't compile. The only thing is, now, if we want to assign a value to an XStringW, we can't do str = "litteral" or L"litteral. I created a method takeValueFrom(). For now let's use str.takeValueFrom("litteral").

We can't do either XStringW str("litteral") or XStringW str(L"litteral"). I created a XStringWP (like a short for XStringW from Pointer). Because it's a subclass, just declare XStringWP("litteral") or XStringWP(L"litteral") and use it as a XStringW.

I can't compile

CLOVERX64.lib(XStringW_test.obj) : error LNK2001: unresolved external symbol "class XStringW global_str1" (?global_str1@@3VXStringW@@A)
CLOVERX64.lib(XStringW_test.obj) : error LNK2001: unresolved external symbol "class XStringW global_str2" (?global_str2@@3VXStringW@@A)
d:\projects\cloverbootloader\Build\Clover\RELEASE_VS2015x86\X64\rEFIt_UEFI\refit\DEBUG\CLOVERX64.dll : fatal error LNK1120: 2 unresolved externals

because they defined as XStringWTest and VS sees different types.

Link to comment
Share on other sites

5 minutes ago, Slice said:

I can't compile


CLOVERX64.lib(XStringW_test.obj) : error LNK2001: unresolved external symbol "class XStringW global_str1" (?global_str1@@3VXStringW@@A)
CLOVERX64.lib(XStringW_test.obj) : error LNK2001: unresolved external symbol "class XStringW global_str2" (?global_str2@@3VXStringW@@A)
d:\projects\cloverbootloader\Build\Clover\RELEASE_VS2015x86\X64\rEFIt_UEFI\refit\DEBUG\CLOVERX64.dll : fatal error LNK1120: 2 unresolved externals

because they defined as XStringWTest and VS sees different types.

I remember to have problem with that if I didn't delete the Build folder (if you compiler with edk build system).

Link to comment
Share on other sites

I compiled with VS

global_test.h contains

extern XStringW global_str1;

while global_test.cpp contains

XStringWTest global_str1(L"global_str1");

And VisualStudio said it is wrong.

Link to comment
Share on other sites

XStringWTest is a XStringW, that's why it's seems valid to me and clang and gcc accepted it. No problem to put XStringWTest in global_test.h

the deleted the lines in "global_test.h" ? There must a problem in XStringW_test.cpp !

Deleting should not be a way a making things work  :)

Link to comment
Share on other sites

Fine, you didn't delete the string global test. And yes, you had to move the class definition to .h.

Although it's not logical that, with VS, you can't do declare extern with a super type. That's the main point of Objects : the possibility the declare subtype and use them not knowing which exact subtype it is. Clang and Gcc seems to agree with me :):). Ah well... Microsoft...

Whatever, it's ok like this, of course.

Link to comment
Share on other sites

 Share

×
×
  • Create New...