A doubly linked-list in C

K

Keith Thompson

Phil Carmody said:
That's what's known as a straw man.

No, it's an analogy.
You can do better, surely? Given that you backed down earlier
in the face of incontrovertable evidence, is Richard's last gasp
still spurring you on? Is it time for the chair to be broken over
the referee's head yet?

Bored now.
 
J

James Kuyper

CBFalconer said:
Ian said:
arnuld said:
Here is FAQ 6.2:

char a[] = "hello";
car *p = "world";

FAQ says that in both cases a[3] or p[3] , the value is same but
compiler gets there differently. Now I have seen my friend using
char *p = "world" notation (for using it as ab array of const
characters). Is it fine or dangerous. Myself, I do const char a[]
= "wordl" all the time, I never ever use char* p notation to point
to some literal but I want to know whether char *p is a good idea
or not.
No, it is not because attempting to modify a string literal gives
you undefined behaviour. Use const char *p.

No, that doesn't help.

First you say it doesn't help,
... That 'const' only gives you the help of having the
compiler emit an error message (probably) when you try to write
into the string.

and then you admit that it does help. It is precisely because of the
help you just mentioned, that he gave this advice.
 
P

Phil Carmody

Richard Heathfield said:
Phil Carmody said:


There are newsgroups for that, e.g. alt.usage.english and
alt.english.usage.

Not really, they have very little interest in the C standard,
and most wouldn't be familiar with the argot used in such
contexts at all.
True enough. Nevertheless, there are some words that have several
senses in English, of which the Standard selects just one sense.

"pass" is certainly not one of them.
There are even some words which the Standard uses in a sense that
is only tangentially related to English (e.g. double, main,
volatile, operator, case, float, register, signed, raise) or even
in a sense that is completely unrelated to the normal English sense
(e.g. char, sin, tan, cosh, log, pow, floor, labs).

Exactly, which is why a.u.e would not be a particularly good
place for such discussions. Evan would probably be the only one
who would be able to give an insightful response at all.
What matters is how the Standard uses the term. The Standard
consistently uses the term "pass" to describe the mechanism by
which argument expressions are made available to functions (and
macros).

You're getting painful now. It _also_ uses the verb in other
contexts, contexts in which others before have used the verb,
such that their usage (apart from the 1 case I highlighted)
does not stand out as being out of place (to me).

No matter how many times you repeat something like "they use
the term in a very strict context" will you be able to counter
a claim that they use the term in a looser context too.

Replace "consistently" with "frequently", and I'd not object
to what you say. However, that would be because you would have
changed your argument to something which is supportable by
evidence rather than simply supported by guesswork and wishful
thinking.
It seems we are not going to reach any kind of consensus on this,
the more so since you seem unwilling or unable to recognise the
possibility that you might be mistaken. (I am mistaken sufficiently
often that I am always open to the possibility that it might happen
again. Perhaps your problem is that you don't make enough
mistakes.)

I am not mistaken about the usage of the previously mentioned English
words in the standard, and have backed it up with clear unambiguous
examples. That's an ontological proof - it cannot be refuted until
the standards committee remove all instances of such usage from the
document. So yes, I do not admit the possibility of error in this
particular case until that happens. If you had a position like mine,
you'd stand by it too, you'd be foolish not to.

Phil
 
P

Phil Carmody

Richard Heathfield said:
Phil Carmody said:


They do, however, have an interest in English usage, which is what
you said you were discussing. Do keep up, there's a good fellow.


Assertion is not evidence. I have provided evidence to support my
view. Do you have any evidence to support your view?

<snip>

Yes, already posted. You missed it as you were desperately trying to
bury your head in the sand trying to avoid it.
I can find no such reference in the Standard, after checking every
single occurrence of "pass". If you have a specific citation in
mind, please let me know what it is so that I can look at it more
closely.

Try conjugating the verb. Use a dictionary to help you if necessary.

Remove the sand from over your head.
Show me a counter-example.

I showed more than one. It's somewhere above ground-level in this
thread. Less digging may help you find it.

In clear sight to those who didn't dive headlong into the
sand at first opportunity.
As far as I can tell, you haven't posted any supporting evidence
from the Standard, and you haven't countered my Standard-based
argument with supporting citation - so yours isn't really much of a
position by which to stand.

Nice beach.

Where have you gone?

Phil
 
C

CBFalconer

Keith said:
On what basis?


The code snippet being discussed is specifically C++ (which was
being used to illustrate a point about C). I strongly suspect
that a C++ compiler would generate code that passes the address
of a location in which the value 5 is stored.

Getting back to C, what exactly do you mean by "copying the pointer
elsewhere and ignoring the error"? You can use a cast to drop the
const qualification, or you can use some kind of type punning to
override it, but I don't think that's what you're talking about.
Can you clarify?

Not really. I'm not in the habit of doing it. But it's useful to
know that some things can be beaten.
 
M

Mark Wooding

Phil Carmody said:
For about teh 5th time, when a reference to i is passed, i is
passed by reference.

I'll bite.

So, if I pass a pointer to a structure, I'm passing the structure itself
by reference, right? And if the structure itself contains further
pointers, I'm actually passing the reachability closure of my original
pointer -- by reference, or meta^n reference or something. Still right?

Suppose I pass a pointer to the first member of a structure. How much
of the structure am I actually passing by reference? What about arrays?

Answers that are as precisely specified as the definitions of
pass-by-value and pass-by-reference that I offered earlier would be most
welcome.

-- [mdw]
 
C

CBFalconer

James said:
CBFalconer said:
Ian said:
arnuld wrote:

Here is FAQ 6.2:

char a[] = "hello";
car *p = "world";

FAQ says that in both cases a[3] or p[3] , the value is same but
compiler gets there differently. Now I have seen my friend using
char *p = "world" notation (for using it as ab array of const
characters). Is it fine or dangerous. Myself, I do const char a[]
= "wordl" all the time, I never ever use char* p notation to point
to some literal but I want to know whether char *p is a good idea
or not.

No, it is not because attempting to modify a string literal gives
you undefined behaviour. Use const char *p.

No, that doesn't help.

First you say it doesn't help,
... That 'const' only gives you the help of having the
compiler emit an error message (probably) when you try to write
into the string.

and then you admit that it does help. It is precisely because of the
help you just mentioned, that he gave this advice.

It doesn't help make the code work. It does help alerting you to
the why.
 
K

Keith Thompson

Richard Heathfield said:
Phil Carmody said:

I can find no such reference in the Standard, after checking every
single occurrence of "pass". If you have a specific citation in
mind, please let me know what it is so that I can look at it more
closely.
[...]

Phil recently posted several relevant quotations from the standard.
He posted snippets of text, taken out of context, with no section
numbers, so it was rather difficult to confirm the quotations. (In at
least one case, the term "pass" wasn't being used to refer to passing
an argument to a C function or macro; see the description of the
system() function, 7.20.4.6p2.)

But taking his list as guidance, and searching n1256 for the word
"pass", I find the following cases where the term is used rather
loosely to refer to some entity being "passed", when what's actually
passed is a pointer to that entity.

First, a footnote that supports the opposite intent, from 6.5.2.2
(it's footnote 81 in N1256; I think it's been quoted here before):

A function may change the values of its parameters, but these
changes cannot affect the values of the arguments. On the other
hand, it is possible to pass a pointer to an object, and the
function may change the value of the object pointed to. A
parameter declared to have array or function type is adjusted to
have a pointer type as described in 6.9.1.

On with the list of places where the term is used more loosely (I
haven't checked this against the list Phil posted):

6.9.1p14 (non-normative):

EXAMPLE 2 To pass one function to another, one might say

int f(void);
/* ... */
g(f);

7.11.1.1p3:

Other implementation-defined strings may be passed as the second
argument to setlocale.

This is also mentioned in J.3.12.

7.15.1.4p6 (non-normative):

EXAMPLE 1 The function f1 gathers into an array a list of
arguments that are pointers to strings (but not more than
MAXARGS arguments), then passes the array as a single argument
to function f2.

7.15.1.4p7 (non-normative):

EXAMPLE 2 The function f3 is similar, but saves the status of the
variable argument list after the indicated number of arguments;
after f2 has been called once with the whole list, the trailing
part of the list is gathered again and passed to function f4.

7.20.5p4,p5 (describing search and sorting utilities):

When the same objects (consisting of size bytes, irrespective of
their current positions in the array) are passed more than once to
the comparison function, the results shall be consistent with one
another.

A sequence point occurs immediately before and immediately after
each call to the comparison function, and also between any call to
the comparison function and any movement of the objects passed as
arguments to that call.

The latter is also mentioned in Annex C, Sequence points.

The above is the result from searching for every occurrence of "pass"
in n1256.pdf. I believe the list is complete, but I'm not certain.

This is essentially 5 distinct cases, only 2 of which are in normative
text. Personally, I'd mark this down to minor sloppiness, not to any
intent to expand the meaning of the word "pass". (I don't mean to
imply that Phil implied any such intent, nor do I mean to denigrate
the members of the committee.)
 
P

Phil Carmody

Mark Wooding said:
I'll bite.

So, if I pass a pointer to a structure, I'm passing the structure itself
by reference, right? And if the structure itself contains further
pointers, I'm actually passing the reachability closure of my original
pointer -- by reference, or meta^n reference or something. Still right?

Firstly, is there any need for the terminology to recurse?
Secondly, a pointer in C does not have an unambiguous meaning,
so it's impossible to say what the reachability closure is.
Suppose I pass a pointer to the first member of a structure. How much
of the structure am I actually passing by reference? What about arrays?

The former, you're only passing the first member by reference.

The latter, you're only explicitly passing a reference to the
pointed-to element in the array; however, C's got riders which
explain how to access, given just a reference to one element of
an array, references to prior and subsequent elements if they
exist, yet doesn't provide a way of telling if they exist, and
so generalisations and attempts at formalisations wouldn't apply
to that special case.
Answers that are as precisely specified as the definitions of
pass-by-value and pass-by-reference that I offered earlier would be most
welcome.

You're confusing accuracy and precision. See a floating point
thread for more info on that. Anyway, they weren't that precise
either. Self-indulgent, I'll grant you.

I've got a far less self-indulgent question for you: do you believe
all terminology in the C standard is both internally consistent, and
consistent with your own personal definitions of the techniques
under discussion?

Phil
 
K

Keith Thompson

Phil Carmody said:
Yes, already posted. You missed it as you were desperately trying to
bury your head in the sand trying to avoid it.

Right, because that's the only possible reason he could have missed
it.

[...]
Try conjugating the verb. Use a dictionary to help you if necessary. [...]
Remove the sand from over your head. [...]
I showed more than one. It's somewhere above ground-level in this
thread. Less digging may help you find it. [...]
In clear sight to those who didn't dive headlong into the
sand at first opportunity. [...]
Nice beach.

Where have you gone?

You had to quote 100+ lines just for that? Please learn to trim.
 
B

Barry Schwarz

Oh yes it does!


Such pointer passing is *explicitly* described as passing a reference.
The concept is passing by reference, the technique used for passing
by reference is passing a pointer by value.

Would you care to provide a reference to this explicit description. My
search of n1256 did not find any occurrence of the word reference in
the context of passing function arguments. In fact, footnote 81
specifically avoids the phrase "pass a reference" when describing
passing a pointer.
 
K

Kaz Kylheku

It probably does!

Since you cannot take the address of 5, you cannot write a standard C++ program
which can test your hypothesis. You can test your hypothesis for arguments of
func which are lvalues, whose address you can take, so that you acn compare
them to the address of ref. But then you have to argue that the call func(5)
uses the same implementation strategy as the call func(x) where x is an lvalue.
Code can be generated for functions such that there are separate entry points
for the two cases (or even separate functions). The value-passing entry point
could work exactly like an int func(int ref); function.
 
I

Ian Collins

CBFalconer said:
No, because the referencing system passes the value by 'pointer'.
That passed 'pointer' effectively has a * permanently prepended,
and you can't remove it. Note that I am talking about the
referencing system, not about C.

True, but the 'pointer' is still passed by value!
This has the disadvantage that the passed value must be in a
'location' that can be accessed. It may allow reading, writing, or
both. But you can't pass in a constant that way.

Not really. The constant value can be pushed on the (mythical) stack
and the address of that location passed.
 
G

Guest

it's up there with with how many angels can dance on the head of a
pin.
In C you have to do something explicitly at call time that is implicit
in
other languages. Some see this as an advantage (I was exposed to too
much Pascal as a egg to agree).


ie. explicit pass by reference

you have C++ in mind I assume
I think the "implementation defined" buzzword was already
covered a few ways back,

what does "in a few ways back mean"? I see no implementation
defined behaviour in the parameter passing mechanism of C
in the manner in which an argument
passing mechanism can actually transfer a value as an
argument,

word salad

and then refer to it within a function (the actual
name of the parameter is yet *another* reference, nobody
seems to have noticed).

I don't see it

So, compilers can use references in all possible cases,
except when an operator (like &) supposedly doesn't allow
it.

Well Fortran compilers pass everything by reference (or they
used to). C compilers pass everything by value.
 The compiler yet needs to make certain that ambiguous
semantics don't cause a program to crash,

what ambiguous semantics? If the semantics are ambiguous
you probably have Undefined Behaviour and the compiler
can generate crashing code if it wishes.

and yet produce
output that is usable in actual programs, and where the
memory actually is, is not the user's business.  The
compiler yet needs to DTRT

what is DTRT?
for all possible contexts,
semantics, architectures, and optimization levels.  It's not
exactly a win, if you're aiming for portability.

why not?
The language specification is less ambiguous on the subject
of passing references (by which, nearly everyone takes to
mean a memory addresses, or have you been discussing some
other language?), because the details of where the location
of the pointer and the space it refers to actually are, can
be completely hidden from the user.  

I think you need to work harder if you expect a simple Markov
Chain to generate something that looks like sense.
 
I

Ian Collins

Kaz said:
Since you cannot take the address of 5, you cannot write a standard C++ program
which can test your hypothesis.

Oh but you can. The function accepts a const reference, so the compiler
may create a temporary int, value 5, and pass that:

extern "C" void f( const int& );

int main()
{
f(5);
}

Compiles to:

movl $5, -8(%ebp)
pushl $0
lea -8(%ebp), %eax
pushl %eax
call f
 
G

Guest

I'm discussing English usage, the standard is written in English.

I think it might be a mistake to think that. It's written in a very
limited and formal version of english.

You can't with a straight face deny the ambiguity of the word
"pass". Actually, you appear to be able to. Others aren't.

I don't think the standard uses "pass" to mean over-take or has
anything to do with urination.
 
B

BartC

Kaz Kylheku said:
Since you cannot take the address of 5, you cannot write a standard C++
program
which can test your hypothesis. You can test your hypothesis for arguments
of

Fortran had no trouble doing this, although the version I used (IV), had no
protection for the callee overwriting constants with a different value.
 
J

James Kuyper

CBFalconer said:
James said:
CBFalconer said:
Ian Collins wrote:
arnuld wrote:

Here is FAQ 6.2:

char a[] = "hello";
car *p = "world";

FAQ says that in both cases a[3] or p[3] , the value is same but
compiler gets there differently. Now I have seen my friend using
char *p = "world" notation (for using it as ab array of const
characters). Is it fine or dangerous. Myself, I do const char a[]
= "wordl" all the time, I never ever use char* p notation to point
to some literal but I want to know whether char *p is a good idea
or not.
No, it is not because attempting to modify a string literal gives
you undefined behaviour. Use const char *p.
No, that doesn't help.
First you say it doesn't help,
... That 'const' only gives you the help of having the
compiler emit an error message (probably) when you try to write
into the string.
and then you admit that it does help. It is precisely because of the
help you just mentioned, that he gave this advice.

It doesn't help make the code work. It does help alerting you to
the why.

Yes, that's precisely the purpose of the suggested code change, and it
strikes me as a pretty good reason for making it.
 
B

BartC

Ian Collins said:
True, but the 'pointer' is still passed by value!

In C, try passing an array by value. You will find it can only be passed by
reference.
Not really. The constant value can be pushed on the (mythical) stack and
the address of that location passed.

That's one inefficient way. Or you can keep the constant in a permanent
static location, and pass the address of that in a single op.
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,265
Latest member
TodLarocca

Latest Threads

Top