0

I don't truly understand it. I am just a student and I notice something in stdio.h

extern FILE *fopen (const char *__restrict __filename,
                 const char *__restrict __modes)

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. Or the one we pass here is address of this filename, but is that address is char type????

-- 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.

--Why in other function prototype like

extern int fseek (FILE *__stream, long int __off, int __whence);

pass "long int __off" not pointer?

kidman1670
  • 21
  • 3

2 Answers2

0

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.

Community
  • 1
  • 1
Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
-1

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. Or the one we pass here is address of this filename, but is that address is char type????

In "C", a string constant (e.g., "hello.txt") is the same as null terminated char array. The address of the string is the position of the first char. For security/reliability, most modern compiler will place those strings into read-only section of the program, and make the type of the constant 'const char **', reducing the change for unexpected program behavior.

dash-o
  • 13,723
  • 1
  • 10
  • 37
  • The type of a string literal does not include `const` regardless of whether the C implementation puts it in read-only storage. – Eric Postpischil Oct 12 '19 at 09:05
  • The -Wwrite-string will make gcc produce warning for char *x = "abcd" ; - same as g++. Better safe than sorry. – dash-o Oct 12 '19 at 17:38