fgets prototype doesn't include const?

J

jaime

Hi all.

According to the fgets wikipedia page, its prototype is:

char* fgets(char *string, int length, FILE * stream)

Given that fgets never assigns to the first parameter (the char
pointer), could the prototype also have been defined as:

char* fgets(char * const string, int length, FILE * stream)

Am I missing something here? (or is it really that "const"s are frequently
omitted?)

TIA, Jaime :)
 
C

Chris Dollin

jaime said:
According to the fgets wikipedia page, its prototype is:

char* fgets(char *string, int length, FILE * stream)
Yes.

Given that fgets never assigns to the first parameter (the char
pointer), could the prototype also have been defined as:

char* fgets(char * const string, int length, FILE * stream)

Doesn't make any difference.
Am I missing something here?

Putting that `const` in the prototype is irrelevant. It makes a
difference in the function /definition/, where it makes the
pointer un-assignableto, but that's not of interest in the
prototype declaration, since one can't assign to the parameter
anyway [1].

[1] Apart from the initialisation on the call, of course.
 
R

Richard Heathfield

jaime said:
Hi all.

According to the fgets wikipedia page, its prototype is:

char* fgets(char *string, int length, FILE * stream)

Given that fgets never assigns to the first parameter (the char
pointer), could the prototype also have been defined as:

char* fgets(char * const string, int length, FILE * stream)

Am I missing something here? (or is it really that "const"s are
frequently omitted?)

You are indeed missing something. It is not guaranteed that fgets never
assigns to the first parameter, and it wouldn't matter if it did, since
C is pass-by-value, so there's no particular value in making the input
parameter const. To do so would place an entirely unnecessary
restriction on the implementation of fgets.

For example, it might want to work something like this:

#include <stdio.h>

/* beware - this is just a sketch, not a tested implementation */
char *fgets(char *_b, int _n, FILE *_f)
{
char *_r = _b;
while(_n-- > 1 && (*_b = getc(_f)) != EOF)
{
++_b; /* _b is modified here - this is a local change, affecting
only the object owned by fgets - it doesn't have any
effect on the value of the object used in the argument
expression during the call. */
}
if(*_b != EOF)
{
*_b = '\0';
}
else
{
_r = NULL;
}
return _r;
}

If _b were const-qualified, this code would not compile.
 
J

jxh

#include <stdio.h>

/* beware - this is just a sketch, not a tested implementation */

Good thing for the warning. A couple of fixups are needed.
char *fgets(char *_b, int _n, FILE *_f)
{
char *_r = _b;
int _c;
while(_n-- > 1 && (_c = getc(_f)) != EOF)
{ *_b++ = _c;
/* _b is modified here - this is a local change, affecting
only the object owned by fgets - it doesn't have any
effect on the value of the object used in the argument
expression during the call. */
if (_c == '\n')
{
break;
}
} if(_c != EOF)
{
*_b = '\0';
}
else
{
_r = NULL;
}
return _r;

}

-- James
 
P

pete

jaime said:
Hi all.

According to the fgets wikipedia page, its prototype is:

char* fgets(char *string, int length, FILE * stream)

Given that fgets never assigns to the first parameter (the char
pointer), could the prototype also have been defined as:

char* fgets(char * const string, int length, FILE * stream)

Am I missing something here?
(or is it really that "const"s are frequently omitted?)

What you are missing is that consts
are always omitted on the parameters.

There are no const qualified parameters
in any standard library function,
for reasons that Richard Heathfield has
already explained elsewhere in this thread.
 
C

CBFalconer

pete said:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);
 
R

Richard Heathfield

CBFalconer said:
pete wrote:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

You are mistaken. The constness here applies to the thing pointed at,
not the pointer itself (i.e. the parameter, which is what pete was
talking about).
 
J

Justin Spahr-Summers

pete said:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

While that prototype does use the "const" keyword, the parameter
itself is not constant. In this instance, it means that the characters
pointed to by "s2" will not be modified. The others were discussing
definitions such as:

char *strcpy(char * const restrict s1, const char * const restrict
s2);

in which the values of the parameters themselves would not be able to
be changed in the implementation of the function, which is kind of a
ridiculous restriction, seeing as it does not affect the calling code.
 
C

CBFalconer

Richard said:
CBFalconer said:
pete wrote:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

You are mistaken. The constness here applies to the thing pointed
at, not the pointer itself (i.e. the parameter, which is what
pete was talking about).

I don't even consider that, since parameters are by value, and any
const attribute can't possibly affect the caller in any way. To my
mind your restriction is totally useless.
 
K

Keith Thompson

CBFalconer said:
Richard said:
CBFalconer said:
pete wrote:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

You are mistaken. The constness here applies to the thing pointed
at, not the pointer itself (i.e. the parameter, which is what
pete was talking about).

I don't even consider that, since parameters are by value, and any
const attribute can't possibly affect the caller in any way.

Yes, that's exactly the point. The OP was asking why fgets is declared as
char* fgets(char *string, int length, FILE * stream);
rather than
char* fgets(char * const string, int length, FILE * stream);

Both pete and Richard were answering that question. I'll grant you
that pete's statement that "[t]here are no const qualified parameters
in any standard library function" was worded imprecisely (it happens).
 
P

pete

CBFalconer said:
Richard said:
CBFalconer said:
pete wrote:
What you are missing is that consts are always omitted on the
parameters. There are no const qualified parameters in any
standard library function, for reasons that Richard Heathfield
has already explained elsewhere in this thread.

You are mistaken. Here is an example from N869:

7.21.2.3 The strcpy function

Synopsis
[#1]
#include <string.h>
char *strcpy(char * restrict s1,
const char * restrict s2);

You are mistaken. The constness here applies to the thing pointed
at, not the pointer itself (i.e. the parameter, which is what
pete was talking about).

I don't even consider that, since parameters are by value, and any
const attribute can't possibly affect the caller in any way. To my
mind your restriction is totally useless.

Each word of your post is within my vocabulary,
but the order in which you've arranged them,
makes no sense to me.

Do you agree or disagree with:
"There are no const qualified parameters
in any standard library function"
?

Are you using this definition of "parameter"?:

N869
3.16
[#1] parameter
formal parameter
formal argument (deprecated)

object declared as part of a function declaration or
definition that acquires a value on entry to the function
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top