Passing a String
why we pass "const char * " ???, if I know this mean pass the pointer to char type constant variable. But __filename like "hello.txt" is strings type, not char type.
C does not have a “strings type.” In C, a string is an array of char
whose end is marked by a null character (a character with value zero). Although in a call such as fopen("myfile", "r")
, we use "myfile"
as an argument, the array "myfile"
is automatically converted to a pointer to its first element. Its first element is a char
, so this pointer is a char *
.
This comes from a rule in the C standard, in C 2018 6.3.2.1 3, which says that any expression with type “array of type” is converted to a pointer to its first element, except when:
- the expression is the operand of
sizeof
or unary &
, or
- is a string literal used to initialize an array (as in
char x[] = "abc";
).
const
in a parameter
The fact that the parameter has type const char *
does not mean we have to pass a pointer to something that is const
. We can pass a plain pointer to a char
, a char *
, and it will be automatically converted to a const char *
. This indicates the function will treat the characters as const
. In other words, the function will only read the characters; it will not modify them.
(Technically, a pointer of type const char *
can be legally converted to char *
and used to modify the objects that are pointed to, as long as those objects were not originally defined with const
. But this is something used for special circumstances. Normal function definitions that use const
in their parameters do not do this.)
__restrict
in a parameter
-- I also confused, is this * belong to __restrict or __filename, is this __restrict is the same as keyword restrict we use when declare normal C function in C99.
__restrict
is used inside some C headers to mean either nothing (when compiling for old versions of C) or restrict
(when compiling for modern versions of C). For example, in the headers Apple distributes with its developer tools, <stdio.h>
includes a header which defines __restrict
this way:
#if __STDC_VERSION__ < 199901
#define __restrict
#else
#define __restrict restrict
#endif
The compiler defines (or omits defining) __STDC_VERSION__
according to the version of C it is compiling for (which can be selected with command-line switches, such as -std=c17
). Then the statements above define __restrict
so that restrict
is not used when compiling for very old versions of C but is used when compiling for modern versions.
Offset for fseek
Why in other function prototype like ...fseek
... pass "long int __off" not pointer?
The off
parameter specifies an offset in a file on disk or other storage. It is not the address of something in main memory, so it is not a pointer. It is a number of bytes from the beginning of the file, so it is a number.