Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > ANNOUNCE ggets revised

Reply
Thread Tools

ANNOUNCE ggets revised

 
 
Old Wolf
Guest
Posts: n/a
 
      06-16-2006
Michael Mair wrote:
>
> As an aside: The only thing open to debate from a C point
> of view is the question whether the header should contain
> #include <stdio.h>
> or not since it "uses" FILE and stdin.


It doesn't use stdin, it contains a macro with stdin in it.
And you can forward-declare FILE on its own.

>As this would mean
> some uglification, e.g.
> # ifdef __cplusplus
> # include <cstdio>
> extern "C" {
> # else
> # include <stdio.h>
> # endif


#include <stdio.h> is correct C++ code.

> I can understand that the appropriate headers are not
> included (ignoring the problem of knowing the appropriate
> header for different C++ implementations).


Well, the C++ standard library has a function that does
the same as what ggets does. So I guess that ggets
would only be used by C++ programmers who do not
want to use the C++ standard library for some reason.

 
Reply With Quote
 
 
 
 
Michael Mair
Guest
Posts: n/a
 
      06-16-2006
Old Wolf schrieb:
> Michael Mair wrote:
>
>>As an aside: The only thing open to debate from a C point
>>of view is the question whether the header should contain
>> #include <stdio.h>
>>or not since it "uses" FILE and stdin.

>
>
> It doesn't use stdin, it contains a macro with stdin in it.


True, thus the "uses".
As soon as you just want to have, for example,

#include <stdlib.h>
#include "ggets.h"
#include "foo.h"

int main (void)
{
char *s = 0;
if (!ggets(&s)) {
foo *bar;
if (bar = calculateFoo(s)) {
outputFoo(bar);
freeFoo(bar);
}
}
free(s);
return 0;
}
you need to #include <stdio.h> even though you do not
obviously "need" it for using ggets(). This is ugly and
a "header defect" like this may not pass code review in
some companies.


> And you can forward-declare FILE on its own.


How can you do so in standard C?
"FILE [...] is an object type capable of recording all the information
needed to control a stream, including its file position indicator,
a pointer to its associated buffer (if any), an error indicator that
records whether a read/write error has occurred, and an end-of-file
indicator that records whether the end of the file has been reached".
If the type were guaranteed to be a typedef for "struct _FILE_T", I'd
agree with you.

>>As this would mean
>>some uglification, e.g.
>> # ifdef __cplusplus
>> # include <cstdio>
>> extern "C" {
>> # else
>> # include <stdio.h>
>> # endif

>
> #include <stdio.h> is correct C++ code.


.... and deprecated. Why risk having to change all include
directives for "stdio" for a new compiler (version)?


>>I can understand that the appropriate headers are not
>>included (ignoring the problem of knowing the appropriate
>>header for different C++ implementations).

>
> Well, the C++ standard library has a function that does
> the same as what ggets does. So I guess that ggets
> would only be used by C++ programmers who do not
> want to use the C++ standard library for some reason.


This is a very reasonable guess. Sometimes, people have
"good" reasons to do more or less unreasonable things,
though.


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
 
 
 
Michael Mair
Guest
Posts: n/a
 
      06-16-2006
CBFalconer schrieb:
> Michael Mair wrote:
>
> ... snip ...
>
>>As an aside: The only thing open to debate from a C point
>>of view is the question whether the header should contain
>> #include <stdio.h>
>>or not since it "uses" FILE and stdin. As this would mean
>>some uglification, e.g.
>> # ifdef __cplusplus
>> # include <cstdio>
>> extern "C" {
>> # else
>> # include <stdio.h>
>> # endif
>>I can understand that the appropriate headers are not
>>included (ignoring the problem of knowing the appropriate
>>header for different C++ implementations).

>
> The header is not intended to enable compilation of ggets via a C++
> compiler, but only the linkage to its code module from a C++
> program.


I am aware of this; the ugliness in my opinion consists of
a header not bringing in everything necessary to use it.
The include problem is one reason why I still accept it as
is; another reason is that you usually need to explicitly
construct a situation where you use fggets()/ggets()
without having included <stdio.h>. The dependence between
the respective include directives still is not overly
joyous even if rules like "standard headers before library
headers before user headers" automatically fix the problem.
YMMV.


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      06-16-2006
Michael Mair wrote:
> CBFalconer schrieb:
>

.... snip ...
>>
>> The header is not intended to enable compilation of ggets via a
>> C++ compiler, but only the linkage to its code module from a C++
>> program.

>
> I am aware of this; the ugliness in my opinion consists of
> a header not bringing in everything necessary to use it.
> The include problem is one reason why I still accept it as
> is; another reason is that you usually need to explicitly
> construct a situation where you use fggets()/ggets()
> without having included <stdio.h>. The dependence between
> the respective include directives still is not overly
> joyous even if rules like "standard headers before library
> headers before user headers" automatically fix the problem.


I disagree that stdio.h is needed to use ggets. The only thing
that might cause trouble is the definition of EOF in the return
value, but detection of a negative value suffices there. So the
using program need only include things that it itself needs. If it
needs the value of EOF, or an output routine, it must include
stdio.h for its own purposes.

The following should function anywhere:

#include <stdlib.h> /* for free */
#include "ggets.h" /* for ggets */

int main(void) {
char *line;

while (0 == ggets(&line) free(line);
return 0;
}

although there may be a difficulty with the value of 'stdin', which
is hidden in the ggets macro.

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews


 
Reply With Quote
 
Frank Silvermann
Guest
Posts: n/a
 
      06-16-2006
CBFalconer wrote:
> Frank Silvermann wrote:
>> CBFalconer wrote:
>>> CBFalconer wrote:
>>>
>>>> I have modified my ggets utility, to simplify the code and reduce
>>>> the requirements on the standard library. The external action is
>>>> totally unchanged, so there is no real need for anyone to upgrade.
>>>> Available at:
>>>>
>>>> <http://cbfalconer.home.att.net/download/>
>>> I hate to admit it, but I released something with a memory leak.
>>> Fixed. The zip file dated 2006-06-15 has the fix, and is now the
>>> only one found on the above link.

>> Did the memory leak exist five minutes ago? I think I got the
>> revised one but my question goes to the header:

>
>>From the time on your article, you got the revised. The ggets.c

> source has a comment about fixing the leak, to double check.

This reply relies on what I can do off-line, which is a nice way of
saying "becoming impatient while my news server pulls the moths out of
the vacuum tubes" I do have the revised version. You put:

int fggets(char* *ln, FILE *f);

#define ggets(ln) fggets(ln, stdin)

in the header in such a manner that if some condition were true, then
any 'tja' within was going to get enclosed by extern "C" { tja } . In
the implementation file you have:


#define INITSIZE 112 /* power of 2 minus 16, helps malloc */
#define DELTASIZE (INITSIZE + 16)

as the only instructions to the preprocessor, except the inclusion of
the header. When is it a good idea to have the preprocessor do the one
as opposed to the other, given that you want to write an ISO C module
that the other guys can access reliably? frank
------
Did Heathfield miss the starting gun?


 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      06-16-2006
Frank Silvermann wrote:
>

.... snip ...
>
> This reply relies on what I can do off-line, which is a nice way of
> saying "becoming impatient while my news server pulls the moths out
> of the vacuum tubes" I do have the revised version. You put:
>
> int fggets(char* *ln, FILE *f);
>
> #define ggets(ln) fggets(ln, stdin)
>
> in the header in such a manner that if some condition were true,
> then any 'tja' within was going to get enclosed by extern "C" { tja }.


I have no idea what you mean by 'tja'. The wrapping in
extern "C" {
}
only occurs when used in a c++ compiler, and prevents the linkage
names being mauled. It does not happen when compiling ggets.o,
because ggets is a C module.

> In the implementation file you have:
>
> #define INITSIZE 112 /* power of 2 minus 16, helps malloc */
> #define DELTASIZE (INITSIZE + 16)
>
> as the only instructions to the preprocessor, except the inclusion of
> the header. When is it a good idea to have the preprocessor do the one
> as opposed to the other, given that you want to write an ISO C module
> that the other guys can access reliably? frank


Why would those go in the header? The headers ONLY purpose is to
export what is needed to link ggets into other modules. No other
module need know anything about those values, they are used only in
the ggets implementation. The preprocessor and the header files
have no special relationship.

--
"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews

 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-16-2006
CBFalconer <(E-Mail Removed)> writes:
[...]
> I disagree that stdio.h is needed to use ggets. The only thing
> that might cause trouble is the definition of EOF in the return
> value, but detection of a negative value suffices there. So the
> using program need only include things that it itself needs. If it
> needs the value of EOF, or an output routine, it must include
> stdio.h for its own purposes.
>
> The following should function anywhere:
>
> #include <stdlib.h> /* for free */
> #include "ggets.h" /* for ggets */
>
> int main(void) {
> char *line;
>
> while (0 == ggets(&line) free(line);
> return 0;
> }
>
> although there may be a difficulty with the value of 'stdin', which
> is hidden in the ggets macro.


I'm not sure what you mean by "although there may be a difficulty".
With a "#include <stdio.h>", there's no problem with the *value* of
stdin, because it's an undeclared identifier. Likewise for FILE.

The expansion of #include "ggets.h" refers to the identifier FILE; the
expansion of ggets(&line) refers to the identifer stdin. How exactly
do you expect the compiler to resolve these identifiers without a
"#include <stdio.h>"?

(You also have a missing right parenthesis, corrected below).

% cat tmp.c
#include <stdlib.h> /* for free */
#include "ggets.h" /* for ggets */

int main(void) {
char *line;

while (0 == ggets(&line)) free(line);
return 0;
}
% gcc -c tmp.c
In file included from tmp.c:2:
ggets.h:37: error: syntax error before 'FILE'
tmp.c: In function 'main':
tmp.c:7: error: 'stdin' undeclared (first use in this function)
tmp.c:7: error: (Each undeclared identifier is reported only once
tmp.c:7: error: for each function it appears in.)

Adding a "#include <stdio.h>" to the top of tmp.c corrects the
problem, but the #include <stdio.h>" should be in "ggets.h".

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
 
Reply With Quote
 
Frank Silvermann
Guest
Posts: n/a
 
      06-16-2006
CBFalconer wrote:
> Frank Silvermann wrote:
> .... snip ...
>> This reply relies on what I can do off-line, which is a nice way of
>> saying "becoming impatient while my news server pulls the moths out
>> of the vacuum tubes" I do have the revised version. You put:
>>
>> int fggets(char* *ln, FILE *f);
>>
>> #define ggets(ln) fggets(ln, stdin)
>>
>> in the header in such a manner that if some condition were true,
>> then any 'tja' within was going to get enclosed by extern "C" { tja }.

>
> I have no idea what you mean by 'tja'. The wrapping in
> extern "C" {
> }
> only occurs when used in a c++ compiler, and prevents the linkage
> names being mauled. It does not happen when compiling ggets.o,
> because ggets is a C module.

There exists no ggets.o file in whatever I unzipped. One is left to
believe that '.o' is a typo or an intermediate file during
compiling-linking.

>> In the implementation file you have:
>>
>> #define INITSIZE 112 /* power of 2 minus 16, helps malloc */
>> #define DELTASIZE (INITSIZE + 16)
>>
>> as the only instructions to the preprocessor, except the inclusion of
>> the header. When is it a good idea to have the preprocessor do the one
>> as opposed to the other, given that you want to write an ISO C module
>> that the other guys can access reliably? frank

>
> Why would those go in the header? The headers ONLY purpose is to
> export what is needed to link ggets into other modules. No other
> module need know anything about those values, they are used only in
> the ggets implementation. The preprocessor and the header files
> have no special relationship.

This last statement is a little shocking, but given the above-stated
purpose of a header and when you think about for a bit, quite true. frank
 
Reply With Quote
 
Randy Howard
Guest
Posts: n/a
 
      06-16-2006
Frank Silvermann wrote
(in article <4493043d$0$30716$(E-Mail Removed)> ):

> CBFalconer wrote:
>> Frank Silvermann wrote:
>> .... snip ...
>>> This reply relies on what I can do off-line, which is a nice way of
>>> saying "becoming impatient while my news server pulls the moths out
>>> of the vacuum tubes" I do have the revised version. You put:
>>>
>>> int fggets(char* *ln, FILE *f);
>>>
>>> #define ggets(ln) fggets(ln, stdin)
>>>
>>> in the header in such a manner that if some condition were true,
>>> then any 'tja' within was going to get enclosed by extern "C" { tja }.

>>
>> I have no idea what you mean by 'tja'. The wrapping in
>> extern "C" {
>> }
>> only occurs when used in a c++ compiler, and prevents the linkage
>> names being mauled. It does not happen when compiling ggets.o,
>> because ggets is a C module.

> There exists no ggets.o file in whatever I unzipped. One is left to
> believe that '.o' is a typo or an intermediate file during
> compiling-linking.


You are new to the C language, aren't you?


--
Randy Howard (2reply remove FOOBAR)
"The power of accurate observation is called cynicism by those
who have not got it." - George Bernard Shaw





 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      06-16-2006
Randy Howard said:

> Frank Silvermann wrote
>> There exists no ggets.o file in whatever I unzipped. One is left to
>> believe that '.o' is a typo or an intermediate file during
>> compiling-linking.

>
> You are new to the C language, aren't you?


That's allowed. From what I've seen so far of Mr Silvermann, I have the
impression that he's fairly new to C but far from dense.

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ANNOUNCE libmsgque 3.5, ANNOUNCE (P)rogramming (L)anguage (M)icro(K)ernel 1.0 Andreas Otto C++ 0 09-25-2009 03:19 PM
ANNOUNCE libmsgque 3.5, ANNOUNCE (P)rogramming (L)anguage (M)icro(K)ernel 1.0 Andreas Otto C Programming 0 09-25-2009 03:16 PM
ANNOUNCE libmsgque 3.5, ANNOUNCE (P)rogramming (L)anguage (M)icro(K)ernel 1.0 Andreas Otto Python 0 09-25-2009 03:14 PM
about ggets() fidlee C Programming 11 12-28-2005 12:05 PM
How do I announce this? (Revised) vbmark Computer Support 22 08-12-2005 12:21 AM



Advertisments