scanf("%s", string) or scanf("%s", &string)? Both work, yet... 
Author Message
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

Both work with gcc, cc, Mac THINK and CodeWarrior, still I can't
believe both variants are semantically equivalent in C!  BTW,
I am an Ada semi-guru in real life.  But I program exclusively in "high-style"
C now, using # define's to obtain Ada front end.  The ADAMANT project I
conduct is to provide a convenient preprocessor level, semi-Ada
"look and feel" in C.

--

  "Ceterum censeo Carthaginem esse delendam"-



Sat, 15 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

Quote:

>Both work with gcc, cc, Mac THINK and CodeWarrior, still I can't
>believe both variants are semantically equivalent in C!  BTW,
>I am an Ada semi-guru in real life.  But I program exclusively in "high-style"
>C now, using # define's to obtain Ada front end.  The ADAMANT project I
>conduct is to provide a convenient preprocessor level, semi-Ada
>"look and feel" in C.

I assume that you have declared string as something like:

        char string[SIZE];

If so, then string has the type "array of SIZE chars".

When you pass string as an argument to scanf, it "decays" into
a pointer to the initial element of the array, which has type
"pointer to char".  Note that the actual value of the pointer
will be the base address of the inital element.

If you pass &string as an argument to scanf, string does NOT
"decay" into a pointer, so the expression &string has type
"pointer to array of SIZE chars".  The important thing here
is that the value of this pointer is the base address of the
array, WHICH IS ALSO THE BASE ADDRESS OF THE INITIAL ELEMENT.

In other words, the two pointers have the same address value, even
though they are different types.

Now scanf expects to receive a pointer of the first type as its
argument (a pointer to char), so techically the second is not
quite right.  However, since scanf takes a variable number of
arguments, the compiler is unable to do type checking, so it
probably won't even give you a warning.

In any case, they will both work, since all scanf does is look
at the address value, regardless of the type.

-Jon



Sat, 15 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...
: Both work with gcc, cc, Mac THINK and CodeWarrior, still I can't
: believe both variants are semantically equivalent in C!  BTW,
: I am an Ada semi-guru in real life.  But I program exclusively in "high-style"
: C now, using # define's to obtain Ada front end.  The ADAMANT project I
: conduct is to provide a convenient preprocessor level, semi-Ada
: "look and feel" in C.

Assuming that "string" was declared as a char*, wouldn't &string be
the address of the pointer, and not the location of where the incoming
data is to be stored?  This does not give a segmentation fault error?
I'm surprised.

-Jeff
--
Jeffrey N. Woodford      | "All the world's indeed a stage, And we are merely

Physical Chemistry Graduate Student, University of Nebraska - Lincoln



Sun, 16 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

Quote:

>Both work with gcc, cc, Mac THINK and CodeWarrior, still I can't
>believe both variants are semantically equivalent in C!  BTW,

    Yes, both are semantically equivalent -- in this particular
case. Read chapter 2 of the FAQ.

--
----
Eric

"If anyone finds this offensive, I am prepared not only to retract my
words, but also to deny under oath that I ever said them." -- Tom Lehrer
----



Sun, 16 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...
assuming
char string[LENGTH];
you can also try
scanf("%s", &(string[0]) );

h.f.s.

--
Hans Friedrich Steffani
Institut fuer Elektrische Maschinen und Antriebe
TU Chemnitz-Zwickau



Sun, 16 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

Quote:
Woodford) writes:

<snip>
|> Assuming that "string" was declared as a char*, wouldn't &string be
|> the address of the pointer, and not the location of where the incoming
|> data is to be stored?  This does not give a segmentation fault error?
|> I'm surprised.

_Assuming_ string was declared char*, and it was assigned to before being
used in scanf, you are right. However, a more likely situation is that string
was declared char[], in which case, string is valid; and &string is not
because it has a different type; and hence possibly a different
representation. Why it works is that char * and char(*)[] hardly ever have
different representations: in fact this point is so subtle that even the
standard gets it wrong (or else almost every program written in C so far is
non-conforming :-) in the description of fprintf.

Cheers
Tanmoy
--

Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87544-0285,USA H:#3,802,9 St,NM87545
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003   voice: 1 (505) 665 4733    [ Home: 1 (505) 662 5596 ]



Sun, 16 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

        Hi all, thanks for the interesting replies on the obscure (<=>
C-ish) scanf().  (-;

        Our local mailserver has a slow link, annoying me when doing
article body search, thus I gained access to the central server
of our Internet provider (our corporate account there is for
"compcom"). It's not telnet that matters, but the search, which
then happens directly there.  Hope it isn't worth explaining in
every posting? A pseudonim Scott Andrews, popping out of the
setting, is OK, I can answer to that...  (-:  (Would appreciate
an advice.)  The following is a rhethoric dialogue with an
anomymous Ada observer (who has a very respectable real
prototype, but w/o approval to disclose yet).

Quote:
> Um, why did you post this to comp.lang.ada?

It's because of the below ADAMANT context.  If we don't have to attach
the '&' in front of the   string,   which indeed is   char *string,
we get closer to Ada!

Quote:
> Anyway, in C the name of an array object, in most expression contexts,
> evaluates to a pointer to the array's first element (exceptions include
> operands of the sizeof and "&" operators; there may be others).
> So, assuming the declaration of "string" is "char *string", yes,
> scanf("%s", string) and scanf("%s", &string) are essentially equivalent.

> Section 6.2.2.1 of the ISO C standard says

>     Except when it is the operand of the sizeof operator or the unary
>     & operator [...], an lvalue that has type "array of _type_" is
>     converted to an expression that has type "pointer to _type_" that
>     points to the initial element of th array object and is not an lvalue.

> The deleted text ("[...]") discusses string literals; _type_ denotes
> the word "type" in italics.

> As I understand it, there may be a slight semantic difference in that
> "string" evaluates to a pointer to a character while "&string" evaluates
> to a pointer to an array of character, but I don't *think* it's likely
> to matter.

        I'll use angle brackets <> below in BNF sense <=> [], as denoting
optional code, or even pseudocode, not to confuse BNF with the C
array[] issue at hand.

        Surely I felt by heart that string, whether declared as   char
*string, or   char string[],   denotes the address of the first
element.  That's why taking one more address _must_ be
semantically different!  The second scanf ought to fill string[0]
(read string[0] as "memory block, starting with string[0],"
depending on the address size) with an address,   so that (char
**)string[0<..n-1>] must be this very address!  Of course it will
be garbage, produced from an input string, according to the
scanf's format specifier for our <&>string, the specifier "%s".
I'm inclined to believe it's a quirk in the implementation of C
library, and how scanf translates "%s" to resolve   &string   to
the same as   string.   It may be how scanf/printf associates the
specifiers with the objects list (NAMELIST in fortran 90 sense
:).  It's known how easy one can get in trouble when the number
of format specifiers doesn't equal the number of the objects on
the NAMELIST, so the issue "string == &string" may hold only
"when it comes to scanf".

        That's exactly what stuns a disciplinary Adaist when looking
at the code in the subject -- in Ada, an access type is always a
next level "wrapper", which doesn't undermine the accessed object
pre-existed structure.  I've seen an interesting "destructor"
implementation in an Ada/Pascal language, and the behavior of '&'
as you describe above reminds me of an "intrusive" destructor,
because its attachment is context-sensitive, not just taking the
address, but implies "evaluation" depending on the argument.
After all, we don't expect "overloading" for & in C!  Yes, it's
implicitly present for "+", "*", etc. C built-in types, but the
address is something which ought to be unequivocal and
straightforward!

        My busy job with C programming for Ada 83 compiler-related
tools has prevented me from staying on top of Ada 95 issues.  Do
people side with a common complaint, when you have to supply a
generic parameter type which, say, is a vector, you also have to
supply its element type separately?  A _type destructor_ would get to
every component of a _type_, with potential nesting, i.e. one have
to supply only the vector, quite naturally.  Of course, the
destructor is a dangerous thing in the limited/private sense, but
why not to allow it in the generic section of a library
compilation unit, and some other well-defined contexts?

I quote a reply, reminding of a type destructor's behavior, here:
        comp.lang.c #126023 (1110 more)

        Subject: Re: scanf("%s", string) or scanf("%s", &string)? Both work, yet...
        Date: Tue May 30 16:34:46 EDT 1995
        Organization: Computer Science Department, Stanford University.
        Lines: 40



        >Both work with gcc, cc, Mac THINK and CodeWarrior, still I can't
        >believe both variants are semantically equivalent in C!  BTW,
        >I am an Ada semi-guru in real life.  But I program exclusively in "high-style"
        >C now, using # define's to obtain Ada front end.  The ADAMANT project I
        >conduct is to provide a convenient preprocessor level, semi-Ada
        >"look and feel" in C.

        I assume that you have declared string as something like:

                char string[SIZE];

        If so, then string has the type "array of SIZE chars".

        When you pass string as an argument to scanf, it "decays" into
        a pointer to the initial element of the array, which has type
        "pointer to char".  Note that the actual value of the pointer
        will be the base address of the inital element.

        If you pass &string as an argument to scanf, string does NOT
        "decay" into a pointer, so the expression &string has type
        "pointer to array of SIZE chars".  The important thing here
        is that the value of this pointer is the base address of the
        array, WHICH IS ALSO THE BASE ADDRESS OF THE INITIAL ELEMENT.

        In other words, the two pointers have the same address value, even
        though they are different types.

        Now scanf expects to receive a pointer of the first type as its
        argument (a pointer to char), so techically the second is not
        quite right.  However, since scanf takes a variable number of
        arguments, the compiler is unable to do type checking, so it
        probably won't even give you a warning.

        In any case, they will both work, since all scanf does is look
        at the address value, regardless of the type.

        -Jon

        So the author in comp.lang.c uses the actual term "decay", describing
to the behavior of & applied to my   char *string.   It means that & in C
behaves similarly to the _type destructor_ described above...  at least
"when it comes to scanf".

--

    ``Age Quod Agis'' (Do what you're doing.)



Mon, 17 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

Quote:


> Woodford) writes:
> <snip>

> _Assuming_ string was declared char*, and it was assigned to before being
> used in scanf, you are right. However, a more likely situation is that string
> was declared char[], in which case, string is valid; and &string is not
> because it has a different type; and hence possibly a different
> representation. Why it works is that char * and char(*)[] hardly ever have
> different representations: in fact this point is so subtle that even the
> standard gets it wrong (or else almost every program written in C so far is
> non-conforming :-) in the description of fprintf.

Actually it's worse than that (Jim).

C leads you to think that char s[]="abcde" and char *s="abcde"
are the same thing, but they are not. In the former, s is a
constant while in the latter it is a variable.

Consider the following code:

char *t="abcde";
char s[]="12345";
main () {
   printf("%08X\n",t);
   printf("%08X\n",&t);
   printf("%08X\n",s);
   printf("%08X\n",&s);
   }

The output is:

000040C8
000040B8
000040BC
000040BC

(On Sunos using acc)

So in the last printf, the & is a no-op.

It should really be flagged as an error. For example, when I
try:

int i;
main () {
    printf("%08X\n",&i);
    printf("%08X\n",& &i );
   }

I get the error message: line 4: unacceptable operand for unary &

I bet if one actually implemented it that way though, there would
be a long line of users outside one's door bearing fire-brands.



Mon, 17 Nov 1997 03:00:00 GMT  
 scanf("%s", string) or scanf("%s", &string)? Both work, yet...

[About:
   string s[]
 and the use of
   &s
]
...
 > It should really be flagged as an error. For example, when I
 > try:
...
 > I get the error message: line 4: unacceptable operand for unary &
 >
 > I bet if one actually implemented it that way though, there would
 > be a long line of users outside one's door bearing fire-brands.
 >
Indeed because &s is correct (but not of type pointer to char it is
of type pointer to array of char).
--
dik t. winter, cwi, kruislaan 413, 1098 sj  amsterdam, nederland, +31205924098



Tue, 18 Nov 1997 03:00:00 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. scanf("%c", &var) behavior!!

2. scanf("%s", &ar[])

3. scanf("%s", &ar[])

4. "scanf" function with assignment-suppression

5. scanf( "%s" ) question

6. handling improper input to "scanf()"

7. Trouble with scanf( "...%[^...]", ...)

8. The effect of "\n" in scanf

9. Setting not Null field to ""(empty string) does not work with CRecordset

10. Setting not Null field to ""(empty string) does not work with CRecordset

11. Looking for a "format(string&, ...)"

12. S"String" and L"String"

 

 
Powered by phpBB® Forum Software