Help in this programm in C

K

Keith Thompson

jacob navia said:
That is not the opinion of the C standards comitee.

We had an animated discussion in comp.std.c about why gets() is
still in the standard, and a certain Mr Gwyn, apparently from the
comitee or very associated with them defended gets() with all
kind of weird arguments.

None of the comitee members cared to contradict him or express another
opinion.

I'm not sure that that's correct, though it may be. A number of
people have participated in that thread, and many (perhaps most) of
them expressed opinions that differed from Doug Gywn's. I don't know
who is on the committee and who isn't. It's entirely possible that
someone who disagreed with Doug Gwyn is also on the committee.
 
K

Keith Thompson

Skarmander said:
Please. We're having a pleasant academic argument, and do not wish to
be disturbed by all sorts of realistic solutions. :)

Sure, while you're adding a garbage collector, link in a safe string
library too, and you've probably covered most C mishaps. (I'd think
out-of-bounds errors and failure to check error returns account for
the remainder.) The context of the discussion was a "vanilla" C
implementation, though, with standard functions considered
dangerous. The standard doesn't prohibit a garbage collecting
implementation, but doesn't guarantee it either.

Garbage collection can break some correct C code. A garbage collector
must avoid deallocating anything that the program is using or may use.
A conforming C program could stash away a pointer value in some manner
that can't be detected by the garbage collector, and later retrieve
and dereference it.

That's not to say that it's a good idea for a program to do something
like that, and I wouldn't object strongly if a future revision of the
C standard made that kind of thing undefined behavior, but it is
something to keep in mind.

Also, I don't believe it's possible to implement garbage collection in
portable C. A garbage collector has to be able to detect any
currently active pointers, which means it has to be able to examine
all active automatic, static, and allocated objects (even ignoring the
issue of pointers being stashed somewhere else). I believe there are
existing garbage collectors that do a good job of this on many
existing systems, but they do so with tricks that are not strictly
portable. (I'm not an expert on garbage collection; please correct me
if I'm mistaken.)
 
R

Richard Heathfield

Keith Thompson said:
[...] I don't believe it's possible to implement garbage collection in
portable C.

And in any case, memory management is far too important to be left to "the
system". (But cf. Lisp!)
 
J

jacob navia

Keith said:
Garbage collection can break some correct C code. A garbage collector
must avoid deallocating anything that the program is using or may use.
A conforming C program could stash away a pointer value in some manner
that can't be detected by the garbage collector, and later retrieve
and dereference it.

Yes, that will not work. Pointers must be left around so that the GC
sees them, what is not very difficult to do. Just do nothing and it
will work !

That's not to say that it's a good idea for a program to do something
like that, and I wouldn't object strongly if a future revision of the
C standard made that kind of thing undefined behavior, but it is
something to keep in mind.

Yes. It was usual for windows programmers to store pointers in the
"window extrabytes", of the window object.

That would not work.
Also, I don't believe it's possible to implement garbage collection in
portable C. A garbage collector has to be able to detect any
currently active pointers, which means it has to be able to examine
all active automatic, static, and allocated objects (even ignoring the
issue of pointers being stashed somewhere else). I believe there are
existing garbage collectors that do a good job of this on many
existing systems, but they do so with tricks that are not strictly
portable. (I'm not an expert on garbage collection; please correct me
if I'm mistaken.)


You can't write many things in C and you need assembly. For instance
to write fe_getenv() you need assembly since acccesing the FPU is
impossible in C.

That is normal practice for the standard library, and it is the same for
the gc library.

In a similar vein, Intel proposes the "standard math kernel" library,
and it is mostly highmly optimized assembly code.
 
I

Ian Collins

Keith said:
Garbage collection can break some correct C code. A garbage collector
must avoid deallocating anything that the program is using or may use.
A conforming C program could stash away a pointer value in some manner
that can't be detected by the garbage collector, and later retrieve
and dereference it.
Not nit picking, just curious: how?
 
B

ballpointpenthief

Dann said:
Right, all you have to do to use it safely is to reopen standard input as a
file, do some seeks and voilla! The gets() function can be used safely.

It's sort of like saying: "You CAN roast marshmallows safely with hydrogen
bombs -- you just have to stand the right distance away."

I don't get what you mean. Can you please explain? Was it a joke?
use fseek()? to where?

Sorry for all the questions.

/* Open stdin as a file. Possibly a piss-take */
#include <stdio.h>
int main(void)
{
FILE *f = fopen(stdin, "r");
if (f == NULL)
return 1;
char buf[10];
for (int i=0; i<10; i++)
buf = fgetc(f);
printf("%s\n", buf);
fclose(f);
return 0;
}

Was it a joke?
 
S

Skarmander

Ian said:
Not nit picking, just curious: how?
Copy the bytes of the pointer to an array of unsigned char. Copy back when
done. The standard requires this to work. (The first stage, at least. I must
admit I haven't looked closely at the guarantees for the second stage.)

This is not likely to occur in a real program. Many if not most other
pointer tricks that defeat GC are not strictly conforming, like the
notorious "XOR two pointer values to implement a doubly linked list" trick.
Many other tricks break the aliasing rules and aren't conforming either.

S.
 
I

Ian Collins

Skarmander said:
Copy the bytes of the pointer to an array of unsigned char. Copy back
when done. The standard requires this to work. (The first stage, at
least. I must admit I haven't looked closely at the guarantees for the
second stage.)
Yuck!

This is not likely to occur in a real program. Many if not most other
pointer tricks that defeat GC are not strictly conforming, like the
notorious "XOR two pointer values to implement a doubly linked list"
trick. Many other tricks break the aliasing rules and aren't conforming
either.
I thought so, I've used a GC library with C before and hadn't run into
any problems.
 
K

Keith Thompson

Skarmander said:
Copy the bytes of the pointer to an array of unsigned char. Copy back
when done. The standard requires this to work. (The first stage, at
least. I must admit I haven't looked closely at the guarantees for the
second stage.)

Simply copying the bytes of a pointer to an array of unsigned char
isn't likely to fool a garbage collector, unless the garbage collector
makes assumptions about the types of objects (which would require a
great deal of chumminess with the compiler).

My understanding is that GC works by scanning memory for things that
look like pointers, and marking anything pointed to by those pointers
as in-use and therefore not available for deallocation. This can
result in some false positives, if something that's not a pointer
happens to contain a bit representation that matches a valid pointer
value. As far as I know, this isn't a major problem in practice.

Copying the bytes of a pointer *and re-ordering them* would fool the
garbage collector (as long as the object from which you copied them is
destroyed).

I can imagine an application that, for security reasons, keeps certain
data structures encrypted most of the time, decrypting them only when
necessary.

I can also imagine an application storing pointers in a file, to be
retrieved later during the same execution of the same program. This
isn't likely to be useful unless you've built some very large
pointer-intensive data structures, and you don't have enough resources
to keep them all in memory all the time.

I presume most garbage collectors provide a mechanism to temporarily
or permanently disable them, either completely or for a given data
structure. A program that does the kind of exotic pointer
manipulation I describe *and* that needs to work in a
garbage-collecting environment would have to take advantage of this
feature.

Also, garbage collection can be impractical in some environments. A
real-time system can't afford to wait for the GC system to analyze
memory while it's trying to meet a hard deadline.
 
J

Joe Wright

ballpointpenthief said:
Dann said:
Right, all you have to do to use it safely is to reopen standard input as a
file, do some seeks and voilla! The gets() function can be used safely.

It's sort of like saying: "You CAN roast marshmallows safely with hydrogen
bombs -- you just have to stand the right distance away."

I don't get what you mean. Can you please explain? Was it a joke?
use fseek()? to where?

Sorry for all the questions.

/* Open stdin as a file. Possibly a piss-take */
#include <stdio.h>
int main(void)
{
FILE *f = fopen(stdin, "r");
if (f == NULL)
return 1;
char buf[10];
for (int i=0; i<10; i++)
buf = fgetc(f);
printf("%s\n", buf);
fclose(f);
return 0;
}

You misunderstand something central. stdin is of type FILE*. stdin is
already open when your program starts.

The first argument to fopen is const char*. stdin cannot be that.

You need more practice.
Was it a joke?
Yes.
 
J

Jiri Slaby

Andrew Poelstra napsal(a):
According to my newserver, I was the first person to actually comment
on the entire code. I've no idea what you mean.

Ok, may be my fault...
1) Tabs are never correct indentation.

why? where?
2) Aside from that, there is no "correct" indentation. 2, 3, or 4-space
is fine. 8 is rarely readable for real code.

I don't think so, that's all.

"Mixing of variable length indent"? Please tell me what that means
and where I did it.

It seemed, that you want him to mix 2 and 4 cols indentation...
It's an output statement. You don't "parse" output. Unless you meant
spellchecked or proofread...

Not you, but the compiler needn't.
 
B

ballpointpenthief

For some reason I want to know if anything like this is possible.
Anyone know how to do this?

/* Attempt to reopen stdin manually as a FILE *
Quite clearly impossible */

#include <stdio.h>
int main(void)
{
long offset;
fclose(stdin);
FILE *f = fopen("readfile.txt", "r");
if (f == NULL)
return 1;
printf("Address of stding: %d / Address of f: %d\n", stdin, f);
offset = (long)f - (long)stdin;
printf("Offset %i\n", offset);
if (fseek(f, offset, SEEK_SET) == -1)
return 1;
printf("New address of f: %p\n", &f);
char buf[10];
fgets(buf, 10, f);
printf("%s\n", buf);
fclose(f);
return 0;
}

You misunderstand something central. stdin is of type FILE*. stdin is
already open when your program starts.

Yeah, just messing.
The first argument to fopen is const char*. stdin cannot be that.

You need more practice.

Good. That means that I'm not wasting my time.
But is it possible?
 
M

Mark McIntyre

Mark McIntyre napsal(a):

Linux kernel is not large enough :D? Then...

Evidently, if 8-space tabs are acceptable....

:)

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
M

Mark McIntyre

Andrew Poelstra napsal(a):

why? where?

Because, as you know from the elsehtread discussion, nobody can agree
on the size and so what looks nicely formatted to you, with tabstops
set to eight, looks hideous to me, with them set to 4, and looks
bizarre in a proportional font. If you use spaces, everything stays
nicely lined up. .
I don't think so, that's all.

As I said elsethread, in large complex programmes, with many levels of
intentation, eight spaces becomes quite unworkable in no time flat. If
you stick to a sensible linelength, by the time you're five or six
levels of indentation in, youre out of space for any actual code.
It seemed, that you want him to mix 2 and 4 cols indentation...

No, he was sayin the code was indifferent to the spacing.
Not you, but the compiler needn't.

I propose to ignore this as it doesn't seem to have any relationship
to the point being made.
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
B

Bill Pursell

Mark McIntyre wrote, in regard to tab vs. space indentation:
Because, as you know from the elsehtread discussion, nobody can agree
on the size and so what looks nicely formatted to you, with tabstops
set to eight, looks hideous to me, with them set to 4, and looks
bizarre in a proportional font. If you use spaces, everything stays
nicely lined up.

With proportional font, nothing stays nicely lined up, whether
you use spaces or tabs.
As I said elsethread, in large complex programmes, with many levels of
intentation, eight spaces becomes quite unworkable in no time flat. If
you stick to a sensible linelength, by the time you're five or six
levels of indentation in, youre out of space for any actual code.

By the time you are at 5 or 6 levels of indentation, you need to
refactor the code. Very rarely is it appropriate to be that
deeply nested. The only time I've ever seen a situation where
it is appropriate to be that deeply nested is in VHDL, where
your first line of actual code is generally indented 3 or 4 levels.
I've never seen a case where it's appropriate in C. A "large
complex program" absolutely must be broken down into
simple manageable components. Modularity really is a
good idea.
 
B

ballpointpenthief

Bill said:
By the time you are at 5 or 6 levels of indentation, you need to
refactor the code. Very rarely is it appropriate to be that
deeply nested. The only time I've ever seen a situation where
it is appropriate to be that deeply nested is in VHDL, where
your first line of actual code is generally indented 3 or 4 levels.
I've never seen a case where it's appropriate in C.

This is from the first ever serious exercise I did. It was a sudoku
solver.

for (int i=0; i<3; i++) // Set up 'box' matrix
for (int j=0; j<3; j++)
for (int k=0; k<3; k++)
for (int l=0; l<3; l++)
for (int m=0; m<9; m++)
if (init->state[(3*i)+k][(3*j)+l] == m+1)
init->box[(3*i)+j][m] = 0;
 
B

ballpointpenthief

ballpointpenthief said:
Bill said:
By the time you are at 5 or 6 levels of indentation, you need to
refactor the code. Very rarely is it appropriate to be that
deeply nested. The only time I've ever seen a situation where
it is appropriate to be that deeply nested is in VHDL, where
your first line of actual code is generally indented 3 or 4 levels.
I've never seen a case where it's appropriate in C.

This is from the first ever serious exercise I did. It was a sudoku
solver.

for (int i=0; i<3; i++) // Set up 'box' matrix
for (int j=0; j<3; j++)
for (int k=0; k<3; k++)
for (int l=0; l<3; l++)
for (int m=0; m<9; m++)
if (init->state[(3*i)+k][(3*j)+l] == m+1)
init->box[(3*i)+j][m] = 0;

I seem to have failed in lining it up aswell.
 
B

Bill Pursell

ballpointpenthief said:
Bill said:
By the time you are at 5 or 6 levels of indentation, you need to
refactor the code. Very rarely is it appropriate to be that
deeply nested. The only time I've ever seen a situation where
it is appropriate to be that deeply nested is in VHDL, where
your first line of actual code is generally indented 3 or 4 levels.
I've never seen a case where it's appropriate in C.

This is from the first ever serious exercise I did. It was a sudoku
solver.

for (int i=0; i<3; i++) // Set up 'box' matrix
for (int j=0; j<3; j++)
for (int k=0; k<3; k++)
for (int l=0; l<3; l++)
for (int m=0; m<9; m++)
if (init->state[(3*i)+k][(3*j)+l] == m+1)
init->box[(3*i)+j][m] = 0;

I think this is intended as an example of code that
requires deep indentation. I think it's actually a great
example of code that needs to be re-designed. One
idea that immediately springs to mind is:

struct value *v;
for (v=start; v<end; v++)
v->box[v->val] = 0;

where v iterates over all the entries in the game grid.
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top