There is fprintf function in Stdio library.
But how to use it?
The first argument is FILE type.
But I have EFI_FILE_PROTOCOL* File which I got from EFIOpenFile function. How to map to FILE type?
There are hosted environments and freestanding environments.
From the C standard:
The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>. A conforming implementation may have extensions (including additional library functions), provided they do not alter the behavior of any strictly conforming program.
So in a freestanding environment (like the UEFI environment you are describing) the C standard doesn't require the fprintf() function to be defined/declared and doesn't require the FILE type to be defined either. Therefore you need to code them on your own.
Related
I am currently learning C. I understand that many common functions, like printf and scanf are not actually part of the C language -- they are part of the "standard library" of functions.
My question is, why aren't such functions built into the language? Is it a philosophical/design consideration? A matter of efficiency when compiling programs? A necessity in order to act as a "middle layer" to ensure compatibility with different operating systems? Something else entirely?
They are part of C. A C implementation consists of a compiler and a library (and other components, like a linker).
The C core language includes facilities that make it possible to write library code that can be used by other programs. The standard library portion of the standard specifies a library that can be implemented using the facilities defined in the core language.
Some languages do have things like a print command built into the language. C's facilities for writing and invoking library code written in C are powerful enough that that's not necessary.
Furthermore, most of the library is optional for "freestanding" implementations (mostly for embedded systems). There are implementations that support the full core language but that don't provide most of the C standard library.
And a compiler and library can be provided separately. For example, gcc is a compiler; it's commonly used with different library implementations on different systems (GNU libc on Linux, "newlib" on Cygwin, the Microsoft library on Windows with MinGW, and so forth). Mixing and matching like that would be much more difficult if the library were integrated into the core language.
The C language standard (the link is to the newest freely available draft) defines C. Section 6 defines the core language; section 7 defines the standard library.
The thing is that standard allows two kinds of conforming implementation: hosted and freestading, see N1570 4/p6:
The two forms of conforming implementation are hosted and
freestanding. A conforming hosted implementation shall accept any
strictly conforming program. A conforming freestanding implementation
shall accept any strictly conforming program that does not use complex
types and in which the use of the features specified in the library
clause (clause 7) is confined to the contents of the standard headers
<float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>,
<stddef.h>, <stdint.h>, and <stdnoreturn.h>. A conforming implementation may have
extensions (including additional library functions), provided they do
not alter the behavior of any strictly conforming program.
By such design, where the libraries are organized as standard headers it's convienent to simply "cut-off" some header if it is not supported.
Note that C standard defines all headers along with function for standard C library. It's included in C standard indeed, not separate thing somewhere else.
They're part of the language, they're just not part of the grammar.
Factoring I/O out into a separate function library buys you the following:
The grammar becomes easier to parse;
You can target a wider range of platforms; any I/O foibles are handled by the library functions, not by hacking the code generator;
You can implement only as much as is needed to support the platform (i.e., an embedded controller probably doesn't need to read or write formatted output);
I can't use setenv() from stdlib.h for C99 standard compiler as it is not available. Is there any other function to set an environment variable in C99?
getenv is thus part of the C90 standard which is included in C99 but setenv is only conform to an IEEE standard so it hasn't to be included in strictly standard C99. Moreover, the corresponding IEEE is from 2001.
This means there isn't any standard way of doing this in C99, you have to use platform-specific code to set the env.
On the freebsd man page:
The getenv() function conforms to ISO/IEC 9899:1990 (ISO C90'').
The setenv(), putenv() and unsetenv() functions conforms to IEEE Std
1003.1-2001 (POSIX.1'').
setenv, putenv and so on should be defined on any POSIX system.
If you're using windows, see this other question which talks about _putenv_s.
I'm surprised that Eclipse can fail to run the simplest program in not only one way but in many way at the same time. The program is
#include <stdio.h>
int main ()
{
int n;
while (scanf("%d", &n) > 0)
{
printf("%d\n", n);
}
return 0;
}
Failure 1: When run in the simulator the output is displayed twice for no reason. The output should be displayed once.
Failure 2: When run with the DE2 board then output is not displayed at all.
Why can't my environment perform like it should?
Since you don't give many details I'm just guessing:
there could be some kind of echoing enabled
on embedded systems <stdio.h> is not required to be supported. <stdio.h> is guaranteed to be available only in hosted environments (i.e. under control of an OS), not in freestanding environments (bare metal).
Quoting from the C99 draft standard N1256:
4. Conformance
[...]
6
The two forms of conforming implementation are hosted and freestanding. A conforming
hosted implementation shall accept any strictly conforming program. A conforming
freestanding implementation shall accept any strictly conforming program that does not
use complex types and in which the use of the features specified in the library clause
(clause 7) is confined to the contents of the standard headers <float.h>,
<iso646.h>, <limits.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, and
<stdint.h>. A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any strictly conforming
program.
You should check the documentation of the compiler for your board to see which headers it supports.
I read this official manual about GCC. Sometimes I have a a problem with translating of text. On the page number six (chapter 2.1) I can't understand such fragment of text:
The ISO C standard defines (in clause 4) two classes of conforming
implementation. A conforming hosted implementation supports the whole
standard including all the library facilities; a conforming
freestanding implementation is only required to provide certain
library facilities: those in <float.h>, <limits.h>, <stdarg.h>, and
<stddef.h>; since AMD1, also those in <iso646.h>; since C99, also
those in <stdbool.h> and <stdint.h>; and since C11, also those in
<stdalign.h> and . In addition, complex types, added in
C99, are not required for freestanding implementations. The standard
also defines two environments for programs, a freestanding
environment, required of all implementations and which may not have
library facilities beyond those required of freestanding
implementations, where the handling of program startup and termination
are implementation-defined, and a hosted environment, which is not
required, in which all the library facilities are provided and startup
is through a function int main (void) or int main (int, char *[]). An
OS kernel would be a freestanding environment; a program using the
facilities of an operating system would normally be in a hosted
implementation.
I am not sure I understand it right...
I will rephrase how I understood it:
Exists two implementations of ISO C standard: a full (named as conforming hosted implementation), and a light (named as conforming freestanding implementation).
Exists two environments (for each of standard's implementation): a hosted environment (for full standard), and a freestanding environment (for light standard).
The light versions is for OS developing. The full versions is for programs, which will work in OS.
And I not understood the phrase about the main function.
I ask to explain me this fragment of text.
It's a bit of both.
The standard defines two runtime environments. One has all of the language, plus a tiny subset of the standard runtime library, plus additional implementation-defined stuff. That's a freestanding environment, and is (as you guessed) intended for programming on the bare metal, e.g. an OS kernel.
The other, more sophisticated environment includes all of the facilities of the above plus all of the standard runtime library. That's a hosted environment, which is intended for application programming.
Now, an implementation is only required to include the facilities of the freestanding environment. If that's all it has, it's called a freestanding implementation. Cross-compilers for deeply embedded microcontrollers are often freestanding implementations, because much of the standard C runtime doesn't make sense or is too big to fit.
Implementing the hosted environment is optional; if an implementation provides the hosted environment it's called a hosted implementation. A hosted implementation must also provide the freestanding environment, i.e. a compilation mode in which only the facilities of a freestanding implementation are available. (This mode would typically be used for compiling things like the C runtime itself, most of which is just more C.)
Finally, the standard signatures for main (int main(void) and int main(int, char **)) are part of the hosted environment. A freestanding environment can use those signatures as well, but it can also define the signature of main to be whatever it likes (void main(void) is common) or use a different name for the entry point.
C11 4/6:
The two forms of conforming implementation are hosted and freestanding. A conforming hosted implementation shall accept any strictly conforming program. A conforming freestanding implementation shall accept any strictly conforming program in which the use of the features specified in the library clause (clause 7) is confined to the contents of the standard headers <float.h>, <iso646.h>, <limits.h>, <stdalign.h>, <stdarg.h>, <stdbool.h>, <stddef.h>, <stdint.h>, and <stdnoreturn.h>.
First note that "implementation", in the context of the C standard, means "the implementation of a C compiler" and nothing else.
As you correctly state in your question, the freestanding implementation is a compiler for a system that isn't intended to have an operative system beneath it. In other words a freestanding implementation compiler produces programs that are either embedded applications running on a "bare bone" CPU, or programs that are operative systems in themselves. While a hosted implementation is a compiler intended for applications running on top of a OS.
The compiler for freestanding applications only needs to provide the above mentioned headers. The rest of the headers (such as stdio.h) are defined in the mentioned "clause 7" of the standard, but they are not mandatory for a freestanding implementation.
Note however that several libraries are not mandatory to neither hosted nor freestanding implementations, for example the complex number library:
C11 7.3.1:
"Implementations that define the macro _ _STDC_NO_COMPLEX_ _ need not
provide this header nor support any of its facilities."
Furthermore, the two different execution environments, freestanding and hosted, allow different syntax for main(), more info can be found here. A very common misunderstanding among programmers is that the only allowed form in C is int main(), which is only true in a hosted environment.
For example, a freestanding program could start at an out-of-reset interrupt service routine. From there it can call a void main() function, or it could call some other function entirely: it is implementation-defined.
What it means is that a freestanding environment is not required to execute your main() function upon startup. For example, it might be looking for _main() instead (the exact name and signature is implementation defined).
Is a C compiler allowed to add functions to standard headers and still conform to the C standard?
I read this somewhere, but I can't find any reference in the standard, except in annex J.5:
The inclusion of any extension that may cause a strictly conforming
program to become invalid renders an implementation nonconforming.
Examples of such extensions are new keywords, extra library functions
declared in standard headers, or predefined macros with names that do
not begin with an underscore.
However, Annex J is informative and not normative... so it isn't helping.
So I wonder if it is okay or not for a conforming compiler to add additional functions in standard headers?
For example, lets say it adds non-standard itoa to stdlib.h.
In 4. "Conformance" ยง6, there is:
A conforming implementation may have extensions (including additional
library functions), provided they do not alter the behavior of any strictly conforming
program.
with the immediate conclusion in a footnote:
This implies that a conforming implementation reserves no identifiers other than those explicitly
reserved in this International Standard.
The reserved identifiers are described in 7.1.3. Basically, it is everything starting with an underscore and everything explicitly listed as used for the standard libraries.
So, yes the compiler is allowed to add extensions. But they have to have a name starting with an underscore or one of the prefixes reserved for libraries.
itoa is not a reserved identifier and a compiler defining it in a standard header is not conforming.
In "7.26 Future library directions" you have a list of the identifiers that may be added to the standard headers, this includes identifiers starting with str or mem, macros starting with E and stuff like that.
Other than that, implementations are restricted to the generic names as reserved in "7.1.3 Reserved identifiers".
Compilers for embedded systems regularly add functions and macros to standard headers, usually to make a special processor feature available for use.
If I read the standard correctly, they can do so without sacrificing conformity if they do use names specified as reserved by the standard. Since a conforming program may use any non-reserved name as a variable or a function name, using such a non-reserved name as an addition to a standard header would break a conforming program.
In practice, however, the compiler writers usually do not care too much. They will at most provide a list of elements defined for the system you may not use if you want your program to work with their implementation.