article on C compiler and standard lib C related to osdev

All about the OSDev Wiki. Discussions about the organization and general structure of articles and how to use the wiki. Request changes here if you don't know how to use the wiki.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

gerryg400 wrote:
h0bby1 wrote:Just need to enable the correct function attributes in function declaration for each compiler. And preferably, choosing a calling convention well supported by the largest number of compilers for each cpu model.
Are you implying that it's possible to build an windows program or even a windows object file with a Linux x86-64 compiler ? Are you positive that the Linux compiler is able to produce PE files ?
ld can produce dll files, cygwin produce dll files, mingw produce dll files, and i think you can install gcc under linux to produce dll files.

but i don't use either so or dll in my os anyway, and they are converted to an internal binary format.

And so i'm pretty positive i can build program under linux that run with a C library compiled under visual studio. and vice versa.

The point here is not to develop exe for linux or windows, but for a self defined os so it's mostly irrelevant if linux can produce exe for windows, but any C compiler can produce exe that will be compatible with each other if some precaution are taken.

and i'm pretty sure you could build a windows program under linux if you have the windows system headers files installed. Actually for x64 they would need to be edited to set the ms calling convention that is not the default under linux, and probably other things.

but what according to you would prevent to build a windows exe under linux ?

people seem to make it look like calling convention are some sort of obscure voodoo magic that is completely compiler specific, but it's not. Compiler has to support correctly at least one calling convention for the cpu architecture it target. And the calling convention used, as well many other thing can be specified either as function attribute or in the build.
Last edited by h0bby1 on Mon Sep 16, 2013 10:57 am, edited 1 time in total.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

gerryg400 wrote:
h0bby1 wrote:you still can't install gcc on a plateform and using it to compile application that use the C library without installing those headers
h0bby1, which headers do you mean by 'those headers' ?
gerryg400 wrote:
h0bby1 wrote:the headers of the C library, stddef.h, stdlib.h, string.h , stdio.h, that are in the package libc-dev on linux
This is not correct. gcc is completely separate from glibc. gcc does not rely on glibc. I have used gcc at work for many years and have never used glibc.
but you need to have one version of the libc installed, and it will most likely be one that is designed specifically for gcc. C Library contain many compiler specific syntax, regarding preprocessor definition and other things. You just can't use just any C Library with any C compiler.

but yes i also used many different compilers with many different libC, some can be compatible, some not.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: article on C compiler and standard lib C related to osde

Post by bluemoon »

I just read again on the wiki page and +1 to what Combuster said:
Combuster wrote:it became somewhat apparent you are seriously misinformed.
Not to offense but I'm trying to point out issue so that the quality of the wiki may be improved.
By the way I appreciate your effort on the page.

I'll try to skip points that mentioned previously.
the C runtime : (crt, libgcc for linux)
libgcc is not C runtime, it's the collection of utility functions like 64-bit and floating point arithmetic used with GCC and has nothing to do with the C specification.
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html
the standard C library : (stdc, glibc for linux), It is implemented in the build environment C library for the particular target, all C compilers must use an implementation of those functions for the target they want to produce working executable for. This include the string and memory management functions (strcpy,memcpy,strtol) , memory allocation functions (malloc,free), floating point math and the ALU, i/o function (printf/sscanf/fopen/fread/fwrite/fclose).
Not true. By target in the compiler context, we means {architecture + object format + OS}. Many of the C library (glibc, ulibc, newlib) do support multiple architectures in source code level, and different OS may implement core stub functions to complete part or full aspect of the library functionalities. object format does not play a role here.
Only the C runtime is generally linked statically because it's small enough, and those functions are totally specific to the compiler.The C library has to be present and loaded by the target system at runtime.
There is nothing to prevent a system to statically link an application with C library. It's better not to confuse reader with facts and your opinion.


The rest of the article is all about how your workaround to problems you faced.
Some of them is plain wrong (malloc.h, seriously?), most of them can be avoided with proper toolchain and usage.
I suggest, once again, you review the related specifications and have better understanding on the subject before putting up a tutorial/wiki.
Try to get facts and references to backup all the claims instead of putting guess work there, that's how it works for wiki / tutorial.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

Griwes wrote:
the client C program use definition of the functions contained in the standard C header files
s/files/includes/, they are not required to be actual files.
ok, they are not necessary actual files. big deal, what does it change ?
Griwes wrote:
malloc.h
This file contain declaration for functions related to memory allocation, such as malloc, calloc, realloc, and free.
No. `malloc`, `calloc`, `realloc` and `free` are declared in <stdlib.h>, and the C standard does not mention anything called "malloc.h". Again, standard includes are not required to be files.
http://stackoverflow.com/questions/1297 ... d-malloc-h

it doesn't really matter if they are files or not, but what they provide as declaration of the functions. and malloc.h can still be used as well and it declare the malloc functions as well, even if it's deprecated.
Griwes wrote:
RTTI (run time type information for c++ virtual classes)
Hardly "the C runtime", also it's part of core language, not of "runtime", whatever that means. There is no such thing as virtual classes in C++. Virtual calls don't rely on RTTI, only exception handling and dynamic_cast rely on RTTI.
if you want to be able to know the actual type of a base virtual class , you need to have RTTI.

http://en.wikipedia.org/wiki/Run-time_type_information
RTTI is available only for classes which are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer.
Griwes wrote:
The simplest is to declare functions with the same parameters and return type than the ones of the compiler, but with a different name. Using a suffix or prefix in the name of the function declaration is generally convenient, application will have to use this name instead of the standard C function name.
No, it's not the simplest. The simplest is to use what C and C++ standards guarantee to be available in a freestanding environment (minus things you'd want to disable yourself, like exceptions and RTTI in C++) and use a proper compiler targeting your target platform.
Each cpu architecture have their own set of calling convention, most intel compiler will support any of those in a standard manner:
"Standard"? What authority approved the standard you are talking about?
who care what authority approved it ? if it's not a holly linux standard then it must be the work of the devil :twisted: ? lol

i don't really care what authority defined the standard, provided that compiler support it, which is the case.

Actually by default gcc-i386 will generate cdecl compatible calls. How do i know ? i don't specify calling convention for gcc, and the program compiled with it are compatible with the one compiled with visual studio with the cdecl attribute. Go figure.

And as Linux system functions declaration doesn't specify calling convention , it's totally safe to assume it's a well defined behavior of gcc.
Griwes wrote:
so this declaration in string.h from gcc C Library header file
It's not GCC C library, it's GNU C library.
and gcc is the GNU C Compiler. It must just be a name coincidence.
Griwes wrote:
would become this in build independent os_string.h
...which is retarded, because in sane setups you can just call it <string.h> and `strcpy`, because the compiler wouldn't find host's version anyway.
how do you define a sane setup that is relevant under windows, linux, mac, bsd, with all the variety of compilers and build environment that they can provide ?
-----------
Griwes wrote: I just skimmed through the text on the wiki, and didn't even try to find brokenness of points about calling conventions, to avoid repeating what has been already said.

Bottom line: only use host compiler when compiling for the host. Each "target triple" consists of (usually) three elements:
- architecture
- OS
- environment (...which is a bit insane name for this, but let's keep it)
that's very linux oriented, on Windows you don't have a 'host compiler' per se, if you imply that host compiler is the compiler that is used to build the host, it's completly irrelevant for non open source platform.
Griwes wrote: You are saying you should not need to use different compiler for the same architecture. It's bullshit. You do not need to use a different compiler for the same TARGET TRIPLE. Do not lie to the compiler. Obviously the ways to achieve target triple specific compilation is different for different compilers:
- for MSVC, as far as I know (but I have not researched the topic) - you are screwed
- for GCC - you build a cross compiler. The time it takes to build it is so short on modern hardware that "it takes time" is totally irrelevant.
- for Clang - you use `-target` switch. It's there since either 3.1 or 3.2, the mechanism used before was a bit more complicated, but there is no reason why anyone would use Clang <3.3 for osdev right now, so it's a non existent issue.
I don't lie to the compiler, i just specify all the compiler specific directive that it need to compile working executable for the platform i target. Not using the 'host compiler default behavior' doesn't mean lieing to the compiler.

MSVC can support compilation for many target, it can compile for ARM, X64 or Win32 by just switching the target plateform in project configuration.

any GCC compiler that support the target cpu architecture can produce exe that will be compatible with exe compiled with another compiler, provided some precautions are taken.
Griwes wrote: There's also problem of a *linker* for given target triple, and you do need to use a target-specific one. As soon as LLVM linker will become usable, I guess it will be just like Clang, so -target will suffice; for GNU ld, just build binutils for target triple. As simple as that.
In my case this problem is eliminated because i convert the elf and PE to an internal format, and name mangling can also be an issue, but it's not in my case because all the import/export tables are parsed to produce uniform name mangling in a single exe format from both elf and PE.
Griwes wrote:
has to support correctly a standard x64 calling convention
Again, what the heck is this "standard calling convention" and what widely accepted document is it described in?
[/quote]

if you really want to find a document that describe the different calling convention for all type of cpu and compiler, you find them, i don't see why it should even matter what authority defined them provided compiler support them, which they do. And which they'd better support to a T if they want the exe they produce to be compatible with the target system.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: article on C compiler and standard lib C related to osde

Post by Griwes »

h0bby1 wrote:
Griwes wrote:
the client C program use definition of the functions contained in the standard C header files
s/files/includes/, they are not required to be actual files.
ok, they are not necessary actual files. big deal, what does it change ?
Terminology. You cannot refer to them as "files".
Griwes wrote:
malloc.h
This file contain declaration for functions related to memory allocation, such as malloc, calloc, realloc, and free.
No. `malloc`, `calloc`, `realloc` and `free` are declared in <stdlib.h>, and the C standard does not mention anything called "malloc.h". Again, standard includes are not required to be files.
http://stackoverflow.com/questions/1297 ... d-malloc-h

it doesn't really matter if they are files or not, but what they provide as declaration of the functions. and malloc.h can still be used as well and it declare the malloc functions as well, even if it's deprecated.
... ... ...

I am not sure if it's worth commenting on this. C standard states they are in <stdlib.h>, eot. The answer under the link you posted says "quite Linux specific". Hence, from these two points, IT'S NOT STANDARD, and you've put it in "standard library" section, which is utterly wrong.
Griwes wrote:
RTTI (run time type information for c++ virtual classes)
Hardly "the C runtime", also it's part of core language, not of "runtime", whatever that means. There is no such thing as virtual classes in C++. Virtual calls don't rely on RTTI, only exception handling and dynamic_cast rely on RTTI.
if you want to be able to know the actual type of a base virtual class , you need to have RTTI.

http://en.wikipedia.org/wiki/Run-time_type_information
RTTI is available only for classes which are polymorphic, which means they have at least one virtual method. In practice, this is not a limitation because base classes must have a virtual destructor to allow objects of derived classes to perform proper cleanup if they are deleted from a base pointer.
You lack the ability to read.

First, there is no such thing as "virtual class" in C++. There are virtual member functions and virtual inheritance, but no such thing as "virtual class" - and neither of these features needs RTTI for anything.

And in majority of cases, if you need to know the actual type of a polymorphic object, you are doing it wrong. The only cases where it's not true and you actually need to do dynamic_cast for sanity are:
1) reimplementing exception handling
2) implementing things like boost.any's .as<>()
Griwes wrote:
The simplest is to declare functions with the same parameters and return type than the ones of the compiler, but with a different name. Using a suffix or prefix in the name of the function declaration is generally convenient, application will have to use this name instead of the standard C function name.
No, it's not the simplest. The simplest is to use what C and C++ standards guarantee to be available in a freestanding environment (minus things you'd want to disable yourself, like exceptions and RTTI in C++) and use a proper compiler targeting your target platform.
Each cpu architecture have their own set of calling convention, most intel compiler will support any of those in a standard manner:
"Standard"? What authority approved the standard you are talking about?
who care what authority approved it ? if it's not a holly linux standard then it must be the work of the devil :twisted: ? lol
What. The. Actual. F*ck. Seriously, man, learn to read. Who the f*ck mentioned "linux standard"? Linux is not a widely recognized standardization organization.
i don't really care what authority defined the standard, provided that compiler support it, which is the case.
Which happens to be the case, but is by no means guaranteed by anything.
Actually by default gcc-i386 will generate cdecl compatible calls. How do i know ? i don't specify calling convention for gcc, and the program compiled with it are compatible with the one compiled with visual studio with the cdecl attribute. Go figure.
Who the hell cares? cdecl is a sane calling convention, so it is used, as simple as that.
And as Linux system functions declaration doesn't specify calling convention , it's totally safe to assume it's a well defined behavior of gcc.
lol. System functions use well-defined ABI (in Linux' case, Sys V ABI), so it's obviously not a problem, but many of us do not want to follow Sys V ABI.
Griwes wrote:
so this declaration in string.h from gcc C Library header file
It's not GCC C library, it's GNU C library.
and gcc is the GNU C Compiler. It must just be a name coincidence.
And Hurd is the GNU OS, hence it must be part of GCC.
Griwes wrote:
would become this in build independent os_string.h
...which is retarded, because in sane setups you can just call it <string.h> and `strcpy`, because the compiler wouldn't find host's version anyway.
how do you define a sane setup that is relevant under windows, linux, mac, bsd, with all the variety of compilers and build environment that they can provide ?
By using a cross compiler (using GCC) or -target switch (using Clang).

Griwes wrote: I just skimmed through the text on the wiki, and didn't even try to find brokenness of points about calling conventions, to avoid repeating what has been already said.

Bottom line: only use host compiler when compiling for the host. Each "target triple" consists of (usually) three elements:
- architecture
- OS
- environment (...which is a bit insane name for this, but let's keep it)
that's very linux oriented, on Windows you don't have a 'host compiler' per se, if you imply that host compiler is the compiler that is used to build the host, it's completly irrelevant for non open source platform.
WTF. WTF. WTF. Have you ever heard the term "POSIX"?

Additionally, MSVC is nothing more than a HOST COMPILER. Same with MinGW targetting Windows. Same with Clang compiling for Windows.

You need to seriously educate yourself.
Griwes wrote: You are saying you should not need to use different compiler for the same architecture. It's bullshit. You do not need to use a different compiler for the same TARGET TRIPLE. Do not lie to the compiler. Obviously the ways to achieve target triple specific compilation is different for different compilers:
- for MSVC, as far as I know (but I have not researched the topic) - you are screwed
- for GCC - you build a cross compiler. The time it takes to build it is so short on modern hardware that "it takes time" is totally irrelevant.
- for Clang - you use `-target` switch. It's there since either 3.1 or 3.2, the mechanism used before was a bit more complicated, but there is no reason why anyone would use Clang <3.3 for osdev right now, so it's a non existent issue.
I don't lie to the compiler, i just specify all the compiler specific directive that it need to compile working executable for the platform i target. Not using the 'host compiler default behavior' doesn't mean lieing to the compiler.
You obviously lie to the compiler - go on, fire your setup up and compile a program outputting value of `__linux__`. Here, `1`. Your compiler thinks its compiling for Linux, while you are not. That's lying.
MSVC can support compilation for many target, it can compile for ARM, X64 or Win32 by just switching the target plateform in project configuration.
So you are agreeing that MSVC is mostly just like Clang?
any GCC compiler that support the target cpu architecture can produce exe that will be compatible with exe compiled with another compiler, provided some precautions are taken.
Yes. Those precautions are called "cross compiling" and "ABI contract".

Anything else works by accident and shall be avoided.
Griwes wrote: There's also problem of a *linker* for given target triple, and you do need to use a target-specific one. As soon as LLVM linker will become usable, I guess it will be just like Clang, so -target will suffice; for GNU ld, just build binutils for target triple. As simple as that.
In my case this problem is eliminated because i convert the elf and PE to an internal format, and name mangling can also be an issue, but it's not in my case because all the import/export tables are parsed to produce uniform name mangling in a single exe format from both elf and PE.
Do you realize you just went full rdos? You never go full rdos.
Griwes wrote:
has to support correctly a standard x64 calling convention
Again, what the heck is this "standard calling convention" and what widely accepted document is it described in?
if you really want to find a document that describe the different calling convention for all type of cpu and compiler, you find them, i don't see why it should even matter what authority defined them provided compiler support them, which they do.
If there is no authority, compiler writers are free to do what the f*ck they want. And break your already broken way of building software.
And which they'd better support to a T if they want the exe they produce to be compatible with the target system.
HERE WE ARE!

Let me quote this again:
And which they'd better support to a T if they want the exe they produce to be compatible with the target system.
You are lying to the compiler about the TARGET SYSTEM by not cross compiling. If it fails, it's not their problem - it's your problem, and it's so bad you even unconsciously agreed with me while trying to disagree, which proves our point.
Last edited by Griwes on Mon Sep 16, 2013 12:01 pm, edited 2 times in total.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

bluemoon wrote:I just read again on the wiki page and +1 to what Combuster said:
Combuster wrote:it became somewhat apparent you are seriously misinformed.
Not to offense but I'm trying to point out issue so that the quality of the wiki may be improved.
By the way I appreciate your effort on the page.
[/quote]

yes i appreciate the feedback, the initial version contained some inaccuracy, or were too specific to some configuration without mentioning it.
bluemoon wrote: I'll try to skip points that mentioned previously.
the C runtime : (crt, libgcc for linux)
libgcc is not C runtime, it's the collection of utility functions like 64-bit and floating point arithmetic used with GCC and has nothing to do with the C specification.
http://gcc.gnu.org/onlinedocs/gccint/Libgcc.html
Yes it's what i say in the article, that libgcc is not part of C standard, and are compiler specific things that the compiler use for a particular cpu target. All compilers have similar things, with Visual it's called the crt, with gcc it's the libgcc, i think most compiler under windows call it the runtime, and they define the same kind of function (_allshl,__allshr, etc) that are not part of C standard, but it's what i say in the article, and they are still things that need to be cared about in some case.

bluemoon wrote:
the standard C library : (stdc, glibc for linux), It is implemented in the build environment C library for the particular target, all C compilers must use an implementation of those functions for the target they want to produce working executable for. This include the string and memory management functions (strcpy,memcpy,strtol) , memory allocation functions (malloc,free), floating point math and the ALU, i/o function (printf/sscanf/fopen/fread/fwrite/fclose).
Not true. By target in the compiler context, we means {architecture + object format + OS}. Many of the C library (glibc, ulibc, newlib) do support multiple architectures in source code level, and different OS may implement core stub functions to complete part or full aspect of the library functionalities. object format does not play a role here.
Well believe or not, i tried once to compile MacOs programs under visual, i unfolded the whole Macos framework file structure to one that is compatible with visual, it could compile but there are many preprocessor definition that the Libc will expect the compiler to set that will provoke errors on compilers that have different predefined preprocessor settings, or different syntax for directive, #pragma, or attributes. Any C Library has to know a few thing about the compiler used to compile program using those declarations. And even most of them contain system and cpu specific directives compiled conditionally based on preprocessor definitions.
bluemoon wrote:
Only the C runtime is generally linked statically because it's small enough, and those functions are totally specific to the compiler.The C library has to be present and loaded by the target system at runtime.
There is nothing to prevent a system to statically link an application with C library. It's better not to confuse reader with facts and your opinion.
Yes it's why i say generally, it's still the most common way to compile C programs, but i specify just after that it can also be linked statically, but by default, most build environment will not link the Lib C statically. And if you have to link statically two program compiled with different libC together, linking the Libc statically is not an option. But for shared library it can be done. It's just not the way it's generally done.

bluemoon wrote: The rest of the article is all about how your workaround to problems you faced.
Some of them is plain wrong (malloc.h, seriously?), most of them can be avoided with proper toolchain and usage.
I suggest, once again, you review the related specifications and have better understanding on the subject before putting up a tutorial/wiki.
Try to get facts and references to backup all the claims instead of putting guess work there, that's how it works for wiki / tutorial.
[/quote]

yes i didn't say the actual version is finished and perfectly accurate, it's just a start, and yes seriously malloc.h will be present in most build environment, but i can change to stdlib as well, actually internally all the C header will include other C headers and will depend on each others, stdio can include stdlib, and both will include some stddef, ctypes, and many other internal files, so the structure of in which files functions are actually declared is not that much well defined.
User avatar
bluemoon
Member
Member
Posts: 1761
Joined: Wed Dec 01, 2010 3:41 am
Location: Hong Kong

Re: article on C compiler and standard lib C related to osde

Post by bluemoon »

[rant]
This is very dangerous to treat things that you've found it work, or more precisely, things that seems to work out, to be true everywhere.
You really should care which specification documented a certain feature or things can break unexpected.
[/rant]
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

Griwes wrote:Terminology. You cannot refer to them as "files".
how should i refer to them then, to use accurate terminology, without using extra complicated syntax to handle many cases that most people will never have to deal with ever ?

Griwes wrote:I am not sure if it's worth commenting on this. C standard states they are in <stdlib.h>, eot. The answer under the link you posted says "quite Linux specific". Hence, from these two points, IT'S NOT STANDARD, and you've put it in "standard library" section, which is utterly wrong.
Ok it's not standard. I'll change it stdlib, but it's also very possible that stdlib will include other 'files' internal to the C Library that the functions will not be defined directly in stdlib.h .
Griwes wrote:You lack the ability to read.

First, there is no such thing as "virtual class" in C++. There are virtual member functions and virtual inheritance, but no such thing as "virtual class" - and neither of these features needs RTTI for anything.

And in majority of cases, if you need to know the actual type of a polymorphic object, you are doing it wrong. The only cases where it's not true and you actually need to do dynamic_cast for sanity are:
1) reimplementing exception handling
2) implementing things like boost.any's .as<>()
A C++ class that define only member as Pure virtual functions can be called a virtual class. If you use a base class in a program, but that the instance of the class is a class derived from it (which is the case anytime you define pure virtual method in a class), then you need RTTI to know the actual object type that the base class as been created as.
Griwes wrote:No, it's not the simplest. The simplest is to use what C and C++ standards guarantee to be available in a freestanding environment (minus things you'd want to disable yourself, like exceptions and RTTI in C++) and use a proper compiler targeting your target platform.
It's the simplest in the case you want to exclude compatibility with any other compiler, and don't care about being compatible with other compilers. Then yes you can use the compiler default, and assume any compiler who doesn't have the same default behavior is incompatible. Which is most the case not true as compiler behavior can be changed with directive. Which is really not all that complicated all together.
Griwes wrote:What. The. Actual. F*ck. Seriously, man, learn to read. Who the f*ck mentioned "linux standard"? Linux is not a widely recognized standardization organization.
Which happens to be the case, but is by no means guaranteed by anything.
it's guaranteed by the fact that if the compiler doesn't follow the standard, it will be unable to use any system functions. It was maybe the case under DOS because there was virtually no shared library, and it was very unlikely a C program would have to call function of another module, as all the system interface was handled via TSR and interupt, but in any 'modern compiler' that can compile exe able to use system api, it's pretty much guaranteed that it will follow some well defined calling convention.
Griwes wrote:Who the hell cares? cdecl is a sane calling convention, so it is used, as simple as that.
Yes, exactly. It's used by most C compiler that can compile exe for i386, and can be specified with function attribute. As simple as that. So it's perfectly safe to assume any C Compiler for i386 will support the cdecl call convention, with a very well defined behavior.
Griwes wrote:]lol. System functions use well-defined ABI (in Linux' case, Sys V ABI), so it's obviously not a problem, but many of us do not want to follow Sys V ABI.
Well then use something else, it doesn't matter what you use if the compiler know what you use and can support it.
Griwes wrote:And Hurd is the GNU OS, hence it must be part of GCC.
Gcc and Glibc are still designed to work fine together on all the most common platform. And other compilers than gcc might not work fine with the Glibc. And other LibC might not work fine with gcc either.
Griwes wrote:By using a cross compiler (using GCC) or -target switch (using Clang).
And if you don't want to use gcc ? this mean that for you,the only 'sane setup' is a setup that use gcc ?

Griwes wrote:WTF. WTF. WTF. Have you ever heard the term "POSIX"?
ok so it's POSIX specific. Have you ever heard of the term 'NT' ? :)
Griwes wrote: Additionally, MSVC is nothing more than a HOST COMPILER. Same with MinGW targetting Windows. Same with Clang compiling for Windows.

You need to seriously educate yourself.
Thanks i take care of my education, and as you mentioned yourself that you don't know visual C well, i'd rather use advise from people who are more educated about it.

Visual C can also be used as a cross compiler, actually it include cross compiler for i386, itanium, x86, arm, potentially others. Visual can produce executable for other platform than the host.
Griwes wrote: You obviously lie to the compiler - go on, fire your setup up and compile a program outputting value of `__linux__`. Here, `1`. Your compiler thinks its compiling for Linux, while you are not. That's lying.
I don't see why i would output the value of '__linux__' as i don't compile exe for a linux platform. I just tell the compiler everything it need to know to compile an exe for the platform i target. It's not lieing, i don't use any compiler or system specific thing. And the compiler know it.
Griwes wrote:Yes. Those precautions are called "cross compiling" and "ABI contract".
ABI contract can be defined explicitly to most C compilers, you don't need a specific compiler to generate code that use a specific ABI contract.
Griwes wrote:Anything else works by accident and shall be avoided.
It doesn't work by accident.
Griwes wrote:You do realize you have just went full rdos? You never go full rdos.
Not sure what you mean by that, but the exe format i use in the os is neither PE or ELF, and it support all the feature of import/export and relocation that can be found in a PE or ELF executable.
Griwes wrote:Again, what the heck is this "standard calling convention" and what widely accepted document is it described in?
Well if you don't what i'm talking about, you should educate yourself about those calling convention. You can find them in google. The calling convention for x64 are very well defined and widely accepted by any compiler that has to produce an executable that will have to use function declaration from another module compiled for x64.
Griwes wrote:If there is no authority, compiler writers are free to do what the f*ck they want. And break your already broken way of building software.
Compiler writer are not free to do whatever they want if they want their exe to be able to use external function declaration. Which most obviously they want to. If compiler writer want to do whatever they want will calling convention, that's fine, but then the exe produced will be incompatible with most system API.

Griwes wrote: HERE WE ARE!

Let me quote this again:
And which they'd better support to a T if they want the exe they produce to be compatible with the target system.
You are lying to the compiler about the TARGET SYSTEM by not cross compiling. If it fails, it's not their problem - it's your problem, and it's so bad you even unconsciously agreed with me while trying to disagree, which proves our point.
I'm not lying to the compiler, i just tell him exactly how to compile anything, the compiler know how it should interpret and use every declaration, and if that doesn't fit the default setting it use for the host platform, then he knows about it.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

bluemoon wrote:[rant]
This is very dangerous to treat things that you've found it work, or more precisely, things that seems to work out, to be true everywhere.
You really should care which specification documented a certain feature or things can break unexpected.
[/rant]
Yes i know that, and i double check in which context the feature i use will be as i expect, and how to specify it to the compiler and building environment otherwise.

But it's also wrong to expect that because you use a cross compiler, it will give a well defined behavior that you can compose with in a safe manner from another building environment.
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: article on C compiler and standard lib C related to osde

Post by dozniak »

h0bby1 wrote:A C++ class that define only member as Pure virtual functions can be called a virtual class.
DIsagree. The official name is 'abstract class'.

Since you seem to be very misinformed, here's direct quote from the c++11 draft:
10.4.2
An abstract class is a class that can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it. A class is abstract if it has at least one pure virtual function.
h0bby1 wrote:Gcc and Glibc are still designed to work fine together on all the most common platform. And other compilers than gcc might not work fine with the Glibc. And other LibC might not work fine with gcc either.
This is utter bullsh*t. Google for newlib, uclibc, clang, icc, dietlibc.
Learn to read.
User avatar
Griwes
Member
Member
Posts: 374
Joined: Sat Jul 30, 2011 10:07 am
Libera.chat IRC: Griwes
Location: Wrocław/Racibórz, Poland
Contact:

Re: article on C compiler and standard lib C related to osde

Post by Griwes »

h0bby1 wrote:
Griwes wrote:Terminology. You cannot refer to them as "files".
how should i refer to them then, to use accurate terminology, without using extra complicated syntax to handle many cases that most people will never have to deal with ever ?
Headers.
Griwes wrote:I am not sure if it's worth commenting on this. C standard states they are in <stdlib.h>, eot. The answer under the link you posted says "quite Linux specific". Hence, from these two points, IT'S NOT STANDARD, and you've put it in "standard library" section, which is utterly wrong.
Ok it's not standard. I'll change it stdlib, but it's also very possible that stdlib will include other 'files' internal to the C Library that the functions will not be defined directly in stdlib.h .
...but it's internal and has no meaning outside particular implementation.
Griwes wrote:You lack the ability to read.

First, there is no such thing as "virtual class" in C++. There are virtual member functions and virtual inheritance, but no such thing as "virtual class" - and neither of these features needs RTTI for anything.

And in majority of cases, if you need to know the actual type of a polymorphic object, you are doing it wrong. The only cases where it's not true and you actually need to do dynamic_cast for sanity are:
1) reimplementing exception handling
2) implementing things like boost.any's .as<>()
A C++ class that define only member as Pure virtual functions can be called a virtual class. If you use a base class in a program, but that the instance of the class is a class derived from it (which is the case anytime you define pure virtual method in a class), then you need RTTI to know the actual object type that the base class as been created as.
No, there is no such thing called "virtual class". I dare you to find term "virtual class" in the ISO 14882.

A class with *a* pure virtual member function is called *abstract class*. "Virtual class" has no meaning in C++.

And I still fail to see a use case for actually using RTTI, except the cases I mentioned. In proper design, outside few isolated cases, RTTI and (derived from it) dynamic_cast are non existent.
Griwes wrote:No, it's not the simplest. The simplest is to use what C and C++ standards guarantee to be available in a freestanding environment (minus things you'd want to disable yourself, like exceptions and RTTI in C++) and use a proper compiler targeting your target platform.
It's the simplest in the case you want to exclude compatibility with any other compiler, and don't care about being compatible with other compilers. Then yes you can use the compiler default, and assume any compiler who doesn't have the same default behavior is incompatible. Which is most the case not true as compiler behavior can be changed with directive. Which is really not all that complicated all together.
No. All sane targets have an ABI that a compiler knows and will always emit correct code. As soon as you start telling the compiler what you are doing, it will do it out of the box.
Griwes wrote:What. The. Actual. F*ck. Seriously, man, learn to read. Who the f*ck mentioned "linux standard"? Linux is not a widely recognized standardization organization.
Which happens to be the case, but is by no means guaranteed by anything.
it's guaranteed by the fact that if the compiler doesn't follow the standard, it will be unable to use any system functions. It was maybe the case under DOS because there was virtually no shared library, and it was very unlikely a C program would have to call function of another module, as all the system interface was handled via TSR and interupt, but in any 'modern compiler' that can compile exe able to use system api, it's pretty much guaranteed that it will follow some well defined calling convention.
You are again mentioning some weird thing you call "the standard", which is gibberish. Also, as you as an osdevver know, you can easily invoke system calls by using `int` or `syscall` or `sysenter`, and they don't follow any "calling convention" and are not invokable from C, so it doesn't matter.

Bottom line here: you don't need to follow any specific calling convention to invoke system calls.
Griwes wrote:Who the hell cares? cdecl is a sane calling convention, so it is used, as simple as that.
Yes, exactly. It's used by most C compiler that can compile exe for i386, and can be specified with function attribute. As simple as that. So it's perfectly safe to assume any C Compiler for i386 will support the cdecl call convention, with a very well defined behavior.
Can, but doing so is not really sane. In sane environment, you will have it out of the box.

Damn, I think I still have some `__attribute__((__cdecl__))` or other bullshit in my code, an artifact of times when I was as stupid as you are now...
Griwes wrote:]lol. System functions use well-defined ABI (in Linux' case, Sys V ABI), so it's obviously not a problem, but many of us do not want to follow Sys V ABI.
Well then use something else, it doesn't matter what you use if the compiler know what you use and can support it.
EXACTLY. That's the reason why you should tell the compiler which specific ABI you are targeting, either by using a cross compiler (for GCC) or by specifying -target switch (for Clang).
Griwes wrote:And Hurd is the GNU OS, hence it must be part of GCC.
Gcc and Glibc are still designed to work fine together on all the most common platform. And other compilers than gcc might not work fine with the Glibc. And other LibC might not work fine with gcc either.
Does not matter. Standard library and compiler are different entities, the same way as "Library" and "Core" are different things in both C and C++.
Griwes wrote:By using a cross compiler (using GCC) or -target switch (using Clang).
And if you don't want to use gcc ? this mean that for you,the only 'sane setup' is a setup that use gcc ?
Quite the contrary. Sane setup does not use any GNU tool, but uses LLVM, which will soon finally fully land on Windows and get a working linker.
Griwes wrote:WTF. WTF. WTF. Have you ever heard the term "POSIX"?
ok so it's POSIX specific. Have you ever heard of the term 'NT' ? :)
No, it's not POSIX specific. I mentioned POSIX, because you seem to think that sanity of cross compilation exist only on Linux, and that Linux is the only POSIXish OS out there.

Stop being this dumb, please.
Griwes wrote: Additionally, MSVC is nothing more than a HOST COMPILER. Same with MinGW targetting Windows. Same with Clang compiling for Windows.

You need to seriously educate yourself.
Thanks i take care of my education, and as you mentioned yourself that you don't know visual C well, i'd rather use advise from people who are more educated about it.

Visual C can also be used as a cross compiler, actually it include cross compiler for i386, itanium, x86, arm, potentially others. Visual can produce executable for other platform than the host.[/quote]Oh yeah, it cross compiles to Windows only. And is not really able to cross compile into anything else. And is still a host compiler.

Clang is also a host compiler. And a cross compiler at the same time. One that is not limited to Windows targets.
Griwes wrote: You obviously lie to the compiler - go on, fire your setup up and compile a program outputting value of `__linux__`. Here, `1`. Your compiler thinks its compiling for Linux, while you are not. That's lying.
I don't see why i would output the value of '__linux__' as i don't compile exe for a linux platform. I just tell the compiler everything it need to know to compile an exe for the platform i target. It's not lieing, i don't use any compiler or system specific thing. And the compiler know it.
No, it doesn't. If you use host compiler to cross compile (wtf), it will think you are compiling for the host - if it's a compiler targeting Linux, it will think it is building for Linux.

There were days when I wasn't using a cross compiler. I got bitten. The fact you haven't been bitten means nothing.
Griwes wrote:Yes. Those precautions are called "cross compiling" and "ABI contract".
ABI contract can be defined explicitly to most C compilers, you don't need a specific compiler to generate code that use a specific ABI contract.
Implicit is better than explicit.
Griwes wrote:Anything else works by accident and shall be avoided.
It doesn't work by accident.
Prove it. I expect a formal proof that a compiler cannot do something breaking your freestanding build when it thinks it's building for, say, FreeBSD (tip: it's not possible to prove it).
Griwes wrote:You do realize you have just went full rdos? You never go full rdos.
Not sure what you mean by that, but the exe format i use in the os is neither PE or ELF, and it support all the feature of import/export and relocation that can be found in a PE or ELF executable.
I mean you just went full "my specific and retarded setup is so limited it accidentally works, and my way is the only correct way despite it being broken and working by accident".

Heck, you went beyond rdos!

You are saying no-one will ever need a cross linker, because in your isolated case, you are not using a binutils linker - it's insane.
Griwes wrote:Again, what the heck is this "standard calling convention" and what widely accepted document is it described in?
Well if you don't what i'm talking about, you should educate yourself about those calling convention. You can find them in google. The calling convention for x64 are very well defined and widely accepted by any compiler that has to produce an executable that will have to use function declaration from another module compiled for x64.
They are very well defined in each individual compiler's documentation. They are recognized. That's true. And yet, your argument is still void.

You are constantly talking as if AMD64 was the only arch out there, or like I couldn't make my own compiler use whatever CC I want. No-one forbids me that. Imagine this situation: my compiler mangles symbols differently than other compilers, my linker resolves the symbols by injecting glue code between different ABIs. But it can do it only for my own OS, because my OS supports this kind of runtime linking, while other OSes don't. On those OSes, my compiler will use their calling conventions, on mine - my own calling conventions.

Now, I am writing portable libraries using just standard C++ and Boost. I cannot afford to have an __attribute__(()) here and there, as the code is supposed to be compiled using different calling conventions on different platforms. There is no other fix to this problem than to tell the compiler what target you are building for.

(Tip: the above paragraph is true even when you disregard my example setup. And yes, that setup is what I am going to implement in my OS.)
Griwes wrote:If there is no authority, compiler writers are free to do what the f*ck they want. And break your already broken way of building software.
Compiler writer are not free to do whatever they want if they want their exe to be able to use external function declaration. Which most obviously they want to. If compiler writer want to do whatever they want will calling convention, that's fine, but then the exe produced will be incompatible with most system API.
They are free to do it. Stop using this empty "if [...]" part, because it's meaningless in this discussion.

And as I've written before, system API is not invoked using C or C++ routines, but by executing `int`, `syscall`, `sysenter` or whatever the OS uses to get into kernel mode. It doesn't care about calling convention. The compiler can just recompile libc or libc++ and stop giving a **** about anything else.
Griwes wrote: HERE WE ARE!

Let me quote this again:
And which they'd better support to a T if they want the exe they produce to be compatible with the target system.
You are lying to the compiler about the TARGET SYSTEM by not cross compiling. If it fails, it's not their problem - it's your problem, and it's so bad you even unconsciously agreed with me while trying to disagree, which proves our point.
I'm not lying to the compiler, i just tell him exactly how to compile anything, the compiler know how it should interpret and use every declaration, and if that doesn't fit the default setting it use for the host platform, then he knows about it.
lol

If you cannot see how telling the compiler "you target this specific platform" and then messing with things it's *far more knowledgeable about than you are* is lying, then I will probably rest my case.

Not to mention the fact you cannot write portable code, if you have attributes naming calling conventions everywhere, and writing non portable code (except in "do_syscall" or in the kernel) is utterly retarded.
Reaver Project :: Repository :: Ohloh project page
<klange> This is a horror story about what happens when you need a hammer and all you have is the skulls of the damned.
<drake1> as long as the lock is read and modified by atomic operations
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

dozniak wrote:
h0bby1 wrote:A C++ class that define only member as Pure virtual functions can be called a virtual class.
DIsagree. The official name is 'abstract class'.

Since you seem to be very misinformed, here's direct quote from the c++11 draft:
10.4.2
An abstract class is a class that can be used only as a base class of some other class; no objects of an abstract class can be created except as subobjects of a class derived from it. A class is abstract if it has at least one pure virtual function.
ok, so it's an abract class. but the term virtual class can also be used.
http://en.wikipedia.org/wiki/Virtual_class
Virtual classes are inner classes of another outer class, which behave like virtual functions. This means they can be overridden in a subclass of the outer class, and the run time type of a virtual class depends on the run time type of an object of the outer class. (Just like the run time type of an object decides which virtual function should be used.)
Like this a run time instance type of the outer class object not only decides on the polymorphic type of his own type object, but also on a whole family tree of virtual class members.
dozniak wrote:
h0bby1 wrote:Gcc and Glibc are still designed to work fine together on all the most common platform. And other compilers than gcc might not work fine with the Glibc. And other LibC might not work fine with gcc either.
This is utter bullsh*t. Google for newlib, uclibc, clang, icc, dietlibc.


try to compile Glibc under visual, and see what happen. Glibc code contain plenty of definition and preprocessor switch that depend on GCC behavior and are specific to it. They are not developed completely independently of each otherr, neither any C Library is made completely independently of any compiler that can use it.


just simple example, is this the new lib you are talking about ?

https://chromium.googlesource.com/nativ ... bc/include

omg what do i see here ? a malloc.h file.

https://chromium.googlesource.com/nativ ... e/malloc.h

now let's see stdlib.h

https://chromium.googlesource.com/nativ ... e/stdlib.h

just the first lines

Code: Select all

#ifdef __CYGWIN__
#include <cygwin/stdlib.h>
#endif

now let's check stdio.h

https://chromium.googlesource.com/nativ ... de/stdio.h

Code: Select all

#ifndef __VALIST
#ifdef __GNUC__
#define __VALIST __gnuc_va_list
#else
#define __VALIST char*
#endif
#endif

omg another use of preprocessor macro used by GCC. they probably just used __GNUC__ by accident and didn't know anything about gcc specific behavior.

Just simple trivial example. that kind of show how obvious it is that any C Library will depend on many compiler specific things, and can't be made totally independently of compiler that will use it.

if you want me to take any of the C Library you mentioned to proove how compiler dependent they are i can do it, but it's rather obvious anyway.

There can be several C library made for a compiler, and several compilers can be supported by a C Library, but the C Library need to know many things about the behavior of any compiler they want to support, even if it's transparent, the Library will use preprocessor switch to select the proper declaration using the syntax specific to any compiler they want to support.
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: article on C compiler and standard lib C related to osde

Post by dozniak »

h0bby1 wrote:ok, so it's an abract class. but the term virtual class can also be used.
http://en.wikipedia.org/wiki/Virtual_class
Virtual classes are inner classes of another outer class, which behave like virtual functions. This means they can be overridden in a subclass of the outer class, and the run time type of a virtual class depends on the run time type of an object of the outer class. (Just like the run time type of an object decides which virtual function should be used.)
Like this a run time instance type of the outer class object not only decides on the polymorphic type of his own type object, but also on a whole family tree of virtual class members.
Did you actually try to READ what you've just quoted?

Virtual class is a very different matter from an abstract class. Please learn to read and read that wikipedia article.
Learn to read.
h0bby1
Member
Member
Posts: 240
Joined: Wed Aug 21, 2013 7:08 am

Re: article on C compiler and standard lib C related to osde

Post by h0bby1 »

dozniak wrote:
h0bby1 wrote:ok, so it's an abract class. but the term virtual class can also be used.
http://en.wikipedia.org/wiki/Virtual_class
Virtual classes are inner classes of another outer class, which behave like virtual functions. This means they can be overridden in a subclass of the outer class, and the run time type of a virtual class depends on the run time type of an object of the outer class. (Just like the run time type of an object decides which virtual function should be used.)
Like this a run time instance type of the outer class object not only decides on the polymorphic type of his own type object, but also on a whole family tree of virtual class members.
Did you actually try to READ what you've just quoted?

Virtual class is a very different matter from an abstract class. Please learn to read and read that wikipedia article.
Still, what i said about virtual class related to runtime type information is still correct. Both abstract class and virtual class use RTTI to find out the type that is used to construct them at runtime. In case of abstract class, it is mandatory to have a class that will override it's member at runtime, and the base class will never be used in the program, so if you want to know the type of an abstract class at runtime, you need RTTI. And same with virtual class that are constructed using a subclass.

There are many case where you need RTTI to deal with the actual type of a virtual or abstract class. It can be avoided, and should not be recommended for 'clean' c++ design, but they are still there.
Last edited by h0bby1 on Mon Sep 16, 2013 3:03 pm, edited 1 time in total.
User avatar
dozniak
Member
Member
Posts: 723
Joined: Thu Jul 12, 2012 7:29 am
Location: Tallinn, Estonia

Re: article on C compiler and standard lib C related to osde

Post by dozniak »

I give up.

Your knowledge of C++ goes well beyond my charted territory.

JFYI: RTTI is usually disabled in well-designed C++ software, just because it is not necessary and incurs some overhead which can be avoided altogether.
Learn to read.
Locked