getline (reprise)

D

dfighter

Franken said:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
{
*p++ = c;
printf("%p %p\n", p, s);
}
if (c == '\n')
{
*p++ = c;
}
*p = '\0';
return p - s;
}

Abridged output:

0022DF69 0022DF60
0022DF6A 0022DF60
0022DF6B 0022DF60
0022DF6C 0022DF60
0022DF6D 0022DF60
0022DF6E 0022DF60
0022DF6F 0022DF60
0022DF70 0022DF60
0022DF71 0022DF60
0022DF72 0022DF60
0022DF73 0022DF60
0022DF74 0022DF60
0022DF75 0022DF60
0022DF76 0022DF60
Because they are memory addresses, and those are integer type datas.
 
K

Keith Thompson

Franken Sense said:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
[snip]

Subtraction of two pointer values yields a signed integer result of
type ptrdiff_t. For more details see
<http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf>,
section 6.5.6 -- or any decent C textbook. Sections 4 and 6 of the
comp.lang.c FAQ, <http://www.c-faq.com/>, may also be helpful.
 
K

Keith Thompson

dfighter said:
Franken said:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p; [snip]
Abridged output:

0022DF69 0022DF60
0022DF6A 0022DF60
0022DF6B 0022DF60
0022DF6C 0022DF60
0022DF6D 0022DF60
0022DF6E 0022DF60
0022DF6F 0022DF60
0022DF70 0022DF60
0022DF71 0022DF60
0022DF72 0022DF60
0022DF73 0022DF60
0022DF74 0022DF60
0022DF75 0022DF60
0022DF76 0022DF60

Because they are memory addresses, and those are integer type datas.

No, it's because that's how subtraction of two pointers is defined.

Pointers are not integers.
 
D

dfighter

Keith said:
dfighter said:
Franken said:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p; [snip]
Abridged output:

0022DF69 0022DF60
0022DF6A 0022DF60
0022DF6B 0022DF60
0022DF6C 0022DF60
0022DF6D 0022DF60
0022DF6E 0022DF60
0022DF6F 0022DF60
0022DF70 0022DF60
0022DF71 0022DF60
0022DF72 0022DF60
0022DF73 0022DF60
0022DF74 0022DF60
0022DF75 0022DF60
0022DF76 0022DF60
Because they are memory addresses, and those are integer type datas.

No, it's because that's how subtraction of two pointers is defined.

Pointers are not integers.
Not C integers, but integer datas, are they not?. I wasn't trying to
tell him that he can store them in integer variables in C. Sorry if I
was ambiguous.
 
F

Franken Sense

If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
{
*p++ = c;
printf("%p %p\n", p, s);
}
if (c == '\n')
{
*p++ = c;
}
*p = '\0';
return p - s;
}

Abridged output:

0022DF69 0022DF60
0022DF6A 0022DF60
0022DF6B 0022DF60
0022DF6C 0022DF60
0022DF6D 0022DF60
0022DF6E 0022DF60
0022DF6F 0022DF60
0022DF70 0022DF60
0022DF71 0022DF60
0022DF72 0022DF60
0022DF73 0022DF60
0022DF74 0022DF60
0022DF75 0022DF60
0022DF76 0022DF60
--
Frank

A brief digression on whether that suspicious-looking mole is actually
cancer. ... Take this simple test called the ABC test. 'A' is for age. What
is your age? Is it over thirteen? If so, it's cancer. That's how the ABC
test works.
~~ Al Franken,
 
K

Keith Thompson

dfighter said:
Keith said:
dfighter said:
Franken Sense wrote:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer? [...]
Because they are memory addresses, and those are integer type datas.

No, it's because that's how subtraction of two pointers is defined.

Pointers are not integers.
Not C integers, but integer datas, are they not?. I wasn't trying to
tell him that he can store them in integer variables in C. Sorry if I
was ambiguous.

Any C object's representation can be interpreted as an array of
unsigned char (bytes). All representations are composed of bits.
So in some sense, everything is an integer. But the mapping from
an object representation to integer values is not necessarily
meaningful.

For example, a typical floating-point representation consists of
a sign bit, an exponent, and a mantissa, each of which can be
interpreted as an integer value; the floating-point value can
be computed from these after some manipulation. (For example,
there's typically an implicit bias on the exponent value and an
implicit leading 1 on the mantissa.) But if you try to interpret
the entire floating-point object's representation as an integer,
you'll get gibberish. Well, you can reconstruct the floating-point
value from it if you know the implementation-specific details, but
there's no straighforward correspondence between the floating-point
value and the type-punned integer value.

The same applies to pointers, except that the standard says even less
about their innards. On many systems, a pointer representation is
a virtual (or perhaps physical) address that can be meaningfully
interpreted as an integer. But the standard carefully avoids
requiring this, or even suggesting it. The closest it comes is a
footnote in C99 6.3.2.3:
The mapping functions for converting a pointer to an integer
or an integer to a pointer are intended to be consistent with
the addressing structure of the execution environment.
but note that it says nothing about what that addressing structure is.

For example, there are real systems where a pointer is represented
as a pair of numbers, a segment number and an offset. On others,
different pointer types can have different representations; I've
worked on one where a word address is a machine address, but a byte
address shoves an offset into the upper 3 bits.

Pointers are not integers. Code that assumes that they are might
work on most systems that you're likely to encounter, but it will
break on others -- and it can often be re-written to use only the
properties of pointer arithmetic guaranteed by the standard.
 
D

dfighter

Keith said:
dfighter said:
Keith said:
Franken Sense wrote:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer? [...]
Because they are memory addresses, and those are integer type datas.
No, it's because that's how subtraction of two pointers is defined.

Pointers are not integers.
Not C integers, but integer datas, are they not?. I wasn't trying to
tell him that he can store them in integer variables in C. Sorry if I
was ambiguous.

Any C object's representation can be interpreted as an array of
unsigned char (bytes). All representations are composed of bits.
So in some sense, everything is an integer. But the mapping from
an object representation to integer values is not necessarily
meaningful.

For example, a typical floating-point representation consists of
a sign bit, an exponent, and a mantissa, each of which can be
interpreted as an integer value; the floating-point value can
be computed from these after some manipulation. (For example,
there's typically an implicit bias on the exponent value and an
implicit leading 1 on the mantissa.) But if you try to interpret
the entire floating-point object's representation as an integer,
you'll get gibberish. Well, you can reconstruct the floating-point
value from it if you know the implementation-specific details, but
there's no straighforward correspondence between the floating-point
value and the type-punned integer value.

The same applies to pointers, except that the standard says even less
about their innards. On many systems, a pointer representation is
a virtual (or perhaps physical) address that can be meaningfully
interpreted as an integer. But the standard carefully avoids
requiring this, or even suggesting it. The closest it comes is a
footnote in C99 6.3.2.3:
The mapping functions for converting a pointer to an integer
or an integer to a pointer are intended to be consistent with
the addressing structure of the execution environment.
but note that it says nothing about what that addressing structure is.

For example, there are real systems where a pointer is represented
as a pair of numbers, a segment number and an offset. On others,
different pointer types can have different representations; I've
worked on one where a word address is a machine address, but a byte
address shoves an offset into the upper 3 bits.

Pointers are not integers. Code that assumes that they are might
work on most systems that you're likely to encounter, but it will
break on others -- and it can often be re-written to use only the
properties of pointer arithmetic guaranteed by the standard.
I see, I had no idea about that memory address representations can be so
different. It shows that I have a lot to learn :)
Thanks for the detailed explanation.
 
I

Ian Collins

Franken said:
In Dread Ink, the Grave Hand of Han from China Did Inscribe:

What difference would it make if it were cast:

return (int)(p - s);

None.

Don't forget sizeof(ptrdiff_t) may be greater than sizeof(int) so (p -
s) can be greater than INT_MAX.
 
F

Franken Sense

In Dread Ink, the Grave Hand of Han from China Did Inscribe:
Make that

printf("%p %p\n", (void *)p, (void *)s);

It's the intent of the standard that you shouldn't have to apply
the casts in this case, since `p' and `s' are of type char *,
but the intent isn't all that explicit outside a footnote.


Assuming you're using getline() correctly, `p - s' yields a signed
integer value of type ptrdiff_t. If the value can't be represented
as a ptrdiff_t, the behavior is undefined.

What difference would it make if it were cast:

return (int)(p - s);

--
Frank

If you put the two Bushs together in their over seven years of their two
presidencies, not one new job has been created. Numbers do not lie. If you
extrapolated from that, if the Bushs had run this country from its very
beginning to the current time, not one American would have ever worked.
We'd be hunter-gatherers.
~~ Al Franken, in response to the 2004 SOTU address
 
F

Franken Sense

In Dread Ink, the Grave Hand of Keith Thompson Did Inscribe:
Franken Sense said:
If p and s are not integers in the following, why is their difference
guaranteed to be an integer?

/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
[snip]

Subtraction of two pointer values yields a signed integer result of
type ptrdiff_t. For more details see
<http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf>,
section 6.5.6 -- or any decent C textbook. Sections 4 and 6 of the
comp.lang.c FAQ, <http://www.c-faq.com/>, may also be helpful.

9 When two pointers are subtracted, both shall point to elements of the
same array object,
or one past the last element of the array object; the result is the
difference of the
subscripts of the two array elements. The size of the result is
implementation-defined,
and its type (a signed integer type) is ptrdiff_t defined in the <stddef.h>
header.
If the result is not representable in an object of that type, the behavior
is undefined. In
other words, if the expressions P and Q point to, respectively, the i-th
and j-th elements of
an array object, the expression (P)-(Q) has the value i−j provided the
value fits in an
object of type ptrdiff_t. Moreover, if the expression P points either to an
element of
an array object or one past the last element of an array object, and the
expression Q points
to the last element of the same array object, the expression ((Q)+1)-(P)
has the same
§6.5.6 Language 83
ISO/IEC 9899:TC3 Committee Draft — Septermber 7, 2007 WG14/N1256
value as ((Q)-(P))+1 and as -((P)-((Q)+1)), and has the value zero if the
expression P points one past the last element of the array object, even
though the
expression (Q)+1 does not point to an element of the array object.91)
10 EXAMPLE Pointer arithmetic is well defined with pointers to variable
length array types.
{
int n = 4, m = 3;
int a[n][m];
int (*p)[m] = a; // p == &a[0]
p += 1; // p == &a[1]
(*p)[2] = 99; // a[1][2] == 99
n = p - a; // n == 1
}
 
F

Franken Sense

In Dread Ink, the Grave Hand of Han from China Did Inscribe:
Incorrect. Bit-fields are objects and are excluded from that.

References: 6.2.6.1{2,4}

Yours,
Han from China

which is reductionistic.

I think it's great that Keith and Han are talking. I've been dealing with
my sisters today, which I find much more difficult than dealing with
threats.

I may have let them down when I didn't disappoint them.
--
Frank

And by the way, a few months ago, I trademarked the word 'funny.' So when
Fox calls me 'unfunny,' they're violating my trademark. I am seriously
considering a countersuit.
~~ Al Franken, in response to Fox's copyright infringement lawsuit
 
K

Keith Thompson

Malcolm McLean said:
We've had this mistake before, but I didn't pick up on it.

What mistake?
The computer represents everything as ones and zeroes. This doesn't mean
that all data is ones and zeroes. The data is what is given, normally, real
numbers, integers, strings, occasionally more exotic things. Just as Jane
Austen is not ink blts and paper, but words. When you scan Jane Austen in,
replacing the ink blots with ones and zeroes, the data is still Jane Austen.

Are you quibbling about my use of the word "everything"? It wasn't
intended to refer to anything outside the scope of C; perhaps I should
have said "all objects".
A floating point number is not an integer. It is, however, two integers and
a boolean.

Combined with a specific interpretation of what those parts mean.
 
J

James Kuyper

Franken said:
In Dread Ink, the Grave Hand of Han from China Did Inscribe:
....
which is reductionistic.

That may be true, but it doesn't make it any less accurate. The cited
section says essentially the same thing that Keith said, but prefixes it
with "Except for bit-fields". The absence of that exception from Keith's
comment is a simplification that renders it inaccurate.
 
J

James Kuyper

Malcolm said:
We've had this mistake before, but I didn't pick up on it.

The computer represents everything as ones and zeroes. This doesn't mean
that all data is ones and zeroes. The data is what is given, normally, real
numbers, integers, strings, occasionally more exotic things. Just as Jane
Austen is not ink blts and paper, but words. When you scan Jane Austen in,
replacing the ink blots with ones and zeroes, the data is still Jane Austen.

A floating point number is not an integer. It is, however, two integers and
a boolean.

You've done no more than expand upon the distinction that Keith was
making between a value and a representation.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,062
Latest member
OrderKetozenseACV

Latest Threads

Top