substring assignment in fortran, C, etc.

  • Follow


I am trying to collect equivalent statements in various languages.

I am now dealing with substring assignment.

Let us assume that string="abcd", value="AB", i=2, j=3 (I won't 
scandalize if in your favourite language it is i=1 j=2 :=). Nor if one 
has to use n=j-i+1 (length("AB")).

I want an assignment which returns string="aABd"

I started from Fortran string(i:j)=value

I came out with the examples below, but cannot find a satisfactory one 
for C using standard library functions.

IDL: strput,string,value,i

Java: string=string.substring(0,i)+value+string.substring(j+1) ;
       or using string buffers
       StringBuffer sb = new StringBuffer(string) ;
       sb.replace(i,j+1,value) ;

awk: string=substr(string,1,i-1) value substr(a,j+1)

mysql: set @string:=insert(@string,@i,@n,@value)

Postscript: string i value putinterval /string exch def

I even have csh

@ i=$i-1
@ j=$j+1
set string=`echo $string | cut -c-$i`$value`echo $string | cut -c$j-`

But what about C ?
I can find an hardcoded solution for a character array

      char a[5]="abcd" ;
      a[1]='A';
      a[2]='B';

which means I can possibly write some for loop

But what if I want a (or string) to be a "standard" string i.e. a
char *a ?


Please note followup to clf

-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/19/2009 4:41:58 PM

In comp.lang.fortran LC's No-Spam Newsreading account 
<nospam@mi.iasf.cnr.it> wrote:

< I am trying to collect equivalent statements in various languages.
 
< I am now dealing with substring assignment.
 
< Let us assume that string="abcd", value="AB", i=2, j=3 (I won't 
< scandalize if in your favourite language it is i=1 j=2 :=). 
< Nor if one has to use n=j-i+1 (length("AB")).
 
< I want an assignment which returns string="aABd"
 
< I started from Fortran string(i:j)=value
 
< I came out with the examples below, but cannot find a 
< satisfactory one for C using standard library functions.
(snip)
 
< But what about C ?
< I can find an hardcoded solution for a character array
 
<      char a[5]="abcd" ;
<      a[1]='A';
<      a[2]='B';
 
< which means I can possibly write some for loop

   char a[]="abcd";
   strncpy(a+1,"AB",2);

or

   strncpy(a+1,"AB",strlen("AB"));

if you don't hard code the 2.

   char a[]="abcd",b[]="AB";
   strncpy(a+1,b,strlen(b));

you are responsible, as usual in C, for not going past the
end of the target string.  The strncpy() function is a little
unusual.  It will copy up to the value of the third argument
characters from the source to the target.  If the terminating
null is reached before the count, the result is null padded
to the specified length.  
 
< But what if I want a (or string) to be a "standard" 
< string i.e. a char *a ?

If you want to add another, PL/I:

   substr(a,2,2)='AB';

-- glen
0
Reply gah (12253) 5/19/2009 5:41:51 PM


Why was your message posted to comp.lang.c, but with followups
redirected only to comp.lang.fortran? Anyone who doesn't notice that
and fix it will be posting his response solely to c.l.f. Any such
message that contains a technical error will not be seen by any of the
C experts on c.l.c, the people most likely to be able to notice and
correct such an error.

LC's No-Spam Newsreading account wrote:
> I am trying to collect equivalent statements in various languages.
>
> I am now dealing with substring assignment.
>
> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
> has to use n=j-i+1 (length("AB")).
>
> I want an assignment which returns string="aABd"
>
> I started from Fortran string(i:j)=value

The closest C equivalent involves a function call, rather than an
assignment. This is inherently the case, since a string is a data
format in C, and it is a format that is stored in an array.  An array
cannot be assigned in C. You could create a C struct type that either
contains a fixed-size array, or points at an array whose size need not
be fixed. Such a struct could value could be assigned, but no such
struct type is part of standard C.
Here is the corresponding function call. It  would use the i=1, j=2
option you mentioned above:

    memcpy(string+i, value, j+1-i)

If string is the name of a pointer, rather than the name of an array,
you can make this an assignment if you want to:

   string = memcpy(string+i, value, j+1-i);

However, there's no good reason to do so, because the assignment
doesn't actually change anything. If you modified the context, such as

    newstring = memcpy(string+i, value, j+1-i);

then the assignment would no longer be pointless; but it would
probably indicate a design error.

....
> But what if I want a (or string) to be a "standard" string i.e. a
> char *a ?

In C, a string is a data format, not a type. That format consists of a
series of char objects, ending with a nul character '\0'. The type
char*a isn't a string type, it's a pointer to a character. That
character might or might not point to a character in a string. If it
does, that string might or might not take up the entire size of an
array of char.

If you're worried about the void* data type returned by memcpy(), you
can convert it:

    (char*)memcpy(string+i, value, j+1-i)
0
Reply jameskuyper (5157) 5/19/2009 5:57:12 PM

LC's No-Spam Newsreading account <nospam@mi.iasf.cnr.it> wrote:

> I came out with the examples below, but cannot find a satisfactory one
> for C using standard library functions.
.... 
> Please note followup to clf

Why? It is a question about how to do something in C. The only Fortran
in sight is just used as an example of what effect you want to achieve.
I don't even see why it was posted to comp.lang.fortran at all, much
less with followups directed solely there. Do you really expect
comp.lang.fortran to be the most appropriate place to discuss how to do
something in C? That makes it sound to me just like an invitation for
language flaming about how painful the Fortran folk might find the C way
of doing something.

-- 
Richard Maine                    | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle           |  -- Mark Twain
0
Reply nospam47 (9742) 5/19/2009 6:21:00 PM

In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
< Why was your message posted to comp.lang.c, but with followups
< redirected only to comp.lang.fortran? Anyone who doesn't notice that
< and fix it will be posting his response solely to c.l.f. Any such
< message that contains a technical error will not be seen by any of the
< C experts on c.l.c, the people most likely to be able to notice and
< correct such an error.
 
< LC's No-Spam Newsreading account wrote:
<> I am trying to collect equivalent statements in various languages.

<> I am now dealing with substring assignment.
(snip)

<> I want an assignment which returns string="aABd"

<> I started from Fortran string(i:j)=value
 
< The closest C equivalent involves a function call, rather than an
< assignment. 

It involves function call syntax, though not necessarily (as I
understand the C standard) an actual function call.  

< This is inherently the case, since a string is a data
< format in C, and it is a format that is stored in an array.  An array
< cannot be assigned in C. 

There has been discussion in comp.lang.fortran on the advantages
and disadvantages of function syntax vs. substring syntax.

There is a disadvantage to Fortran substring syntax, especially
in the lvalue case, in that it doesn't generalize.  You can't,
for example, directly substring a substring:  

   string(i:j)(k:l) isn't legal.

(snip)

< Here is the corresponding function call. It  would use the 
< i=1, j=2 option you mentioned above:
 
<    memcpy(string+i, value, j+1-i)

My choice would be  strncpy(string+i, value, j+1-i);
but I agree that memcpy will also work.  Keeping to the str...
functions for string work seems more consistent.
 
< If string is the name of a pointer, rather than the name of an 
< array, you can make this an assignment if you want to:

(snip discussion about strings and pointers in C, not so
relevant to the OP question.)

As I mentioned in a post not follow up to comp.lang.c, the
PL/I form is:

   substr(a,2,2)='AB';  or more generally

   substr(string,i,j+1-i)=value;

Again, note function syntax but not a function.  
(PL/I calls them pseudo-variables.)  This is consistent
with the function call syntax in expressions.

-- glen
0
Reply gah (12253) 5/19/2009 6:56:42 PM

On May 19, 12:41=A0pm, LC's No-Spam Newsreading account
<nos...@mi.iasf.cnr.it> wrote:
> I am trying to collect equivalent statements in various languages.
>
> I am now dealing with substring assignment.
>
> Let us assume that string=3D"abcd", value=3D"AB", i=3D2, j=3D3 (I won't
> scandalize if in your favourite language it is i=3D1 j=3D2 :=3D). Nor if =
one
> has to use n=3Dj-i+1 (length("AB")).
>
> I want an assignment which returns string=3D"aABd"
>
> I started from Fortran string(i:j)=3Dvalue
>
> I came out with the examples below, but cannot find a satisfactory one
> for C using standard library functions.
>
> IDL: strput,string,value,i
>
> Java: string=3Dstring.substring(0,i)+value+string.substring(j+1) ;
> =A0 =A0 =A0 =A0or using string buffers
> =A0 =A0 =A0 =A0StringBuffer sb =3D new StringBuffer(string) ;
> =A0 =A0 =A0 =A0sb.replace(i,j+1,value) ;
>
> awk: string=3Dsubstr(string,1,i-1) value substr(a,j+1)
>
> mysql: set @string:=3Dinsert(@string,@i,@n,@value)
>
> Postscript: string i value putinterval /string exch def
>
> I even have csh
>
> @ i=3D$i-1
> @ j=3D$j+1
> set string=3D`echo $string | cut -c-$i`$value`echo $string | cut -c$j-`
>
> But what about C ?
> I can find an hardcoded solution for a character array
>
> =A0 =A0 =A0 char a[5]=3D"abcd" ;
> =A0 =A0 =A0 a[1]=3D'A';
> =A0 =A0 =A0 a[2]=3D'B';
>
> which means I can possibly write some for loop
>
> But what if I want a (or string) to be a "standard" string i.e. a
> char *a ?
>
> Please note followup to clf

In C a "string" is an array of characters. You can only assign values
to one element of the array at a time. If you do assign what you think
is a "string", like "AB" to a[1], you get a compiler warning and a
strange result, which I leave to the people in comp.lang.c to explain.

In Fortran, an array of characters is not the same as a character
("string") variable.

You can assign an array slice to a slice of an array of characters in
Fortran, but the right hand size is an array constructed of individual
characters. I do not expect that this helps you much. [frown]

IIRC, in COBOL, you can work with both constructs at the same time
through REDEFINES. Perhaps you might like to add COBOL to your list of
languages? (later standards allow "reference modification"). [smile]

--- e





0
Reply epc8 (1259) 5/19/2009 7:25:02 PM

glen herrmannsfeldt wrote:
> In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
....
> <> I want an assignment which returns string="aABd"
>
> <> I started from Fortran string(i:j)=value
>
> < The closest C equivalent involves a function call, rather than an
> < assignment.
>
> It involves function call syntax, though not necessarily (as I
> understand the C standard) an actual function call.

True; but it's a distinction of negligible importance; it's possible
for a C compiler to inline some or all of any call to a function if
the definition of that function is known to the compiler; highly
optimizing C compilers inline more code than you might expect. In
practice, it's simpler to just refer to them as function calls, and
not worry about the details of what the compiler actually does with
them.

....
> < Here is the corresponding function call. It  would use the
> < i=1, j=2 option you mentioned above:
>
> <    memcpy(string+i, value, j+1-i)
>
> My choice would be  strncpy(string+i, value, j+1-i);
> but I agree that memcpy will also work.  Keeping to the str...
> functions for string work seems more consistent.

The desired functionality is underdefined; the difference between your
version and mine matters only if "value" is shorter than the substring
it is replacing. My version has possible undefined behavior in that
case; yours avoids that, at the cost of being very marginally slower
for large sub strings. What does fortran code given above do in that
case?
0
Reply jameskuyper (5157) 5/19/2009 7:51:35 PM

In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
< glen herrmannsfeldt wrote:
<> In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
< ...

<> < The closest C equivalent involves a function call, 
<> < rather than an assignment.

<> It involves function call syntax, though not necessarily (as I
<> understand the C standard) an actual function call.
 
< True; but it's a distinction of negligible importance; it's possible
< for a C compiler to inline some or all of any call to a function if
< the definition of that function is known to the compiler; 

I would agree, except that the OP question is pretty much
a question of syntax, not of the underlying implementation.

The non-function-call syntax of the other languages mentioned
may actually be implemented as a function call.  

< highly
< optimizing C compilers inline more code than you might expect. In
< practice, it's simpler to just refer to them as function calls, and
< not worry about the details of what the compiler actually does with
< them.

(snip on memcpy vs. strncpy)
 
< The desired functionality is underdefined; the difference between your
< version and mine matters only if "value" is shorter than the substring
< it is replacing. My version has possible undefined behavior in that
< case; yours avoids that, at the cost of being very marginally slower
< for large sub strings. What does fortran code given above do in that
< case?

The general rule is that Fortran pads with blanks.  When CHARACTER
was added to Fortran in Fortran 77 the lengths were always known
at compile time.  CHARACTER variables had a fixed length and were
padded with blanks when a shorter value was stored.  I believe that
is true for the OP examples of substring assignment, but I am not
so sure in all possible cases.

-- glen
0
Reply gah (12253) 5/19/2009 9:04:56 PM

glen herrmannsfeldt wrote:
....
> The general rule is that Fortran pads with blanks.  When CHARACTER
> was added to Fortran in Fortran 77 the lengths were always known
> at compile time.  CHARACTER variables had a fixed length and were
> padded with blanks when a shorter value was stored.  I believe that
> is true for the OP examples of substring assignment, but I am not
> so sure in all possible cases.

The function call

     sprintf(string+i, "%-*.*s%s", j+1-i, j+1-i, value, string+j);

would handle padding with blanks as you describe if value were too
short, if it weren't for the fact that it has undefined behavior
(because of the overlap between the output string and the input
string). If newstring were a seperate char array containing enough
space to store the result, or a pointer to the first element of such
an array, then

    sprintf(newstring, "%*.*s%-*.*s%s", i, i, string, j+1-i, j+1-i,
value, string+j);

would do the job with well-defined behavior.
You can write C code to do just about anything you want with a string;
but C's built-in string-oriented capabilities are not in the same
league as those of, say, perl.
0
Reply jameskuyper (5157) 5/19/2009 10:06:14 PM

"jameskuyper" <jameskuyper@verizon.net> wrote in message 
news:525bc618-fcfe-45e8-a6e1-3133a1cc79db@r34g2000vba.googlegroups.com...

> LC's No-Spam Newsreading account wrote:
>> I am trying to collect equivalent statements in various languages.

>> I am now dealing with substring assignment.

>> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
>> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
>> has to use n=j-i+1 (length("AB")).

>> I want an assignment which returns string="aABd"

But why didn't you more properly torture c.l.c. with an example
like:

C:\gfortran\clf\Cstr>type Cstr.f90
program Cstr
   implicit none
   character(*), parameter :: abcd = 'abcd'
   character(len(abcd)) string(8)
   character(*), parameter :: AB = 'AB'
   integer pos

   string = abcd
   pos = 2
   string(:)(pos:pos+len(AB)-1) = AB
   write(*,'(a)') string
end program Cstr

C:\gfortran\clf\Cstr>gfortran Cstr.f90 -oCstr

C:\gfortran\clf\Cstr>Cstr
aABd
aABd
aABd
aABd
aABd
aABd
aABd
aABd

?

-- 
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0
Reply not_valid (1681) 5/19/2009 11:41:10 PM

"James Van Buskirk" <not_valid@comcast.net> wrote in message
news:guvg2o$393$1@news.eternal-september.org...
> "jameskuyper" <jameskuyper@verizon.net> wrote in message
> news:525bc618-fcfe-45e8-a6e1-3133a1cc79db@r34g2000vba.googlegroups.com...
>
>> LC's No-Spam Newsreading account wrote:
>>> I am trying to collect equivalent statements in various languages.
>
>>> I am now dealing with substring assignment.
>
>>> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
>>> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
>>> has to use n=j-i+1 (length("AB")).
>
>>> I want an assignment which returns string="aABd"
>
> But why didn't you more properly torture c.l.c. with an example
> like:

>   character(*), parameter :: AB = 'AB'
>   string(:)(pos:pos+len(AB)-1) = AB
>   write(*,'(a)') string
....

I don't get this. Didn't Fortran use to be even more crude and basic than C?

So how did the Fortran committees manage to bring it into the 21st century
(and still call it Fortran), while C is still languishing in the 1970s it
seems?

-- 
Bart

0
Reply bartc (783) 5/20/2009 8:50:46 AM

On Tue, 19 May 2009, Richard Maine wrote:
> LC's No-Spam Newsreading account wrote:
>
>> I came out with the examples below, but cannot find a satisfactory one
>> for C using standard library functions.
> ...
>> Please note followup to clf
>
> Why? It is a question about how to do something in C.

Apologies if this seemed inappropriate. My reasons were twofold. One is 
that I read sort of regularly clf and keep it "caught up" while I do not 
read regularly clc. The other one is that I wanted to get an answer from 
somebody who was fluent in both languages (my question was not only "how 
to do something in C" but "how to do in C something similar to the way 
one does in Fortran"), say "the intersection of knowledgeable users on 
clf and clc".

> Do you really expect comp.lang.fortran to be the most appropriate 
> place to discuss how to do something in C? That makes it sound to me 
> just like an invitation for language flaming

I wanted to avoid flames, and apparently have been successful, all the 
replies are rather technical and up to the point ! Thanks !

-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/20/2009 8:58:22 AM

jameskuyper <jameskuyper@verizon.net> wrote:

> If you're worried about the void* data type returned by memcpy(), you
> can convert it:
> 
>     (char*)memcpy(string+i, value, j+1-i)

But don't do that, because adding unnecessary casts is a very bad idea,
which will trip you up on those few occasions when you _do_ need one.

Richard
0
Reply raltbos (821) 5/20/2009 9:12:43 AM

In article <GvPQl.31248$OO7.10079@text.news.virginmedia.com>,
BartC <bartc@freeuk.com> wrote:
>
>"James Van Buskirk" <not_valid@comcast.net> wrote in message
>news:guvg2o$393$1@news.eternal-september.org...
>
>I don't get this. Didn't Fortran use to be even more crude and basic than C?

That's a fair claim - though it's also disputable.

>So how did the Fortran committees manage to bring it into the 21st century
>(and still call it Fortran), while C is still languishing in the 1970s it
>seems?

By vendor innovation, using traditional ISO standards' methodology,
being prepared to accept lessons from other languages, and hard work.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/20/2009 9:40:57 AM

LC's No-Spam Newsreading account wrote:
> On Tue, 19 May 2009, Richard Maine wrote:
>> LC's No-Spam Newsreading account wrote:
>>
>>> I came out with the examples below, but cannot find a satisfactory one
>>> for C using standard library functions.
>> ...
>>> Please note followup to clf
>>
>> Why? It is a question about how to do something in C.
> 
> Apologies if this seemed inappropriate. My reasons were twofold. One is 
> that I read sort of regularly clf and keep it "caught up" while I do not 
> read regularly clc.

If you had not set followup to c.l.f, you would still have seen all 
replies on either group; there would be no need for you to read c.l.c, 
but those of use who read c.l.c and not c.l.f could still see the responses.

> ... The other one is that I wanted to get an answer from 
> somebody who was fluent in both languages (my question was not only "how 
> to do something in C" but "how to do in C something similar to the way 
> one does in Fortran"), say "the intersection of knowledgeable users on 
> clf and clc".

If that's what you were looking for, you could have single-posted to 
either group. Those in that intersection would have seen it, no matter 
which of the two groups you posted it to. Since you follow c.l.f, that 
would have been the appropriate one. I think you would have gotten fewer 
answers that way, less quickly, and possibly less accurate ones.

>> Do you really expect comp.lang.fortran to be the most appropriate 
>> place to discuss how to do something in C? That makes it sound to me 
>> just like an invitation for language flaming
> 
> I wanted to avoid flames, and apparently have been successful, all the 
> replies are rather technical and up to the point ! Thanks !

I think your question requires more C expertise than Fortran expertise, 
so cross-posting it (and NOT re-directing followups) would have been 
more appropriate.
0
Reply jameskuyper (5157) 5/20/2009 10:41:50 AM

On 20 May, 10:40, n...@cam.ac.uk wrote:
> In article <GvPQl.31248$OO7.10...@text.news.virginmedia.com>,
> BartC <ba...@freeuk.com> wrote:

<snip>

> >I don't get this. Didn't Fortran use to be even more crude and basic than C?

> That's a fair claim - though it's also disputable.

Hollerith strings

<snip>
0
Reply nick_keighley_nospam (4574) 5/20/2009 3:03:32 PM

On 19 May, 17:41, LC's No-Spam Newsreading account
<nos...@mi.iasf.cnr.it> wrote:

> I am trying to collect equivalent statements in various languages.

you  might get a broader range of languages if you tried
comp.programming


> I am now dealing with substring assignment.
>
> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
> has to use n=j-i+1 (length("AB")).
>
> I want an assignment which returns string="aABd"

you want the assignment statement to return something (C's does for
instance)
or you want it to modify the string?

> I started from Fortran string(i:j)=value

<snip>

this is my attempt at a scheme version

(define (string-embed old-str embed-str posn)
    (if (< posn 0)
        (error "STRING-EMBED: bad position specified"))

    (if (> (+ posn (string-length embed-str)) (string-length old-str))
        (error "STRING-EMBED: not enough room"))

    (let ((start (substring old-str 0 posn))
          (middle embed-str)
          (end (substring old-str (+ posn (string-length embed-str))
(string-length old-str))))

        (string-append start middle end)))

(string-embed "abcd" "AB" 1)


This may not match your spec. as it doesn't actually modify old-str
it produces a new string.

This version modifies the original string (I've stripped out the
error checking to amke it shorter)

(define (string-embed! old-str embed-str posn)
    (define (cp-str old-str embed-str posn)
        (if (not (string-empty? embed-str))
            (begin
                (string-set! old-str posn (string-ref embed-str 0))
                (cp-str
                    old-str
                    (substring embed-str 1 (string-length embed-str))
                    (+ posn 1)))))
    (cp-str old-str embed-str posn))


It uses an internal helper function.
This version uses scheme's "named let" to avoid the helper
function (think of it as calling the loop again with new parameters)

(define (string-embed! old-str embed-str posn)
    (let loop ((embed-str embed-str) (posn posn))
        (if (not (string-empty? embed-str))
            (begin
                (string-set! old-str posn (string-ref embed-str 0))
                (loop
                    (substring embed-str 1 (string-length embed-str))
                    (+ posn 1))))))


--
Nick Keighley

> Callbacks are a form of continuation.
Yes, in the same sense that a shoe is a form of aircraft carrier.
0
Reply nick_keighley_nospam (4574) 5/20/2009 3:12:32 PM

LC's No-Spam Newsreading account <nospam@mi.iasf.cnr.it> writes:

> I am trying to collect equivalent statements in various languages.

This is rather useless an endeavour.  Anecdotic at most.

The syntactic differences are irrelevant.  

Semantically... Already, here you use the term "statement"; in some
languages there's a distinction between statements and expressions
(eg. in C or Pascal), but in other languages, there's only expressions
(eg. Lisp or Ruby).  So, let's say that in different languages you may
have similar elements, but since their semantics are different, you
cannot consider them to be equivalent.  
http://en.wikipedia.org/wiki/Formal_semantics_of_programming_languages

For example, "assignment" in C, vs. in Common Lisp:

             x=42;           (setq x 42)

The meaning of these expressions is totally different.

In C, each variable can hold only a statically given type.  Therefore
assignment must also include a type conversion step.  IF x as been
declared as a float, then the semantics of x=42; will be:
    
    convert-integer-to-float(42) -> t1
    get-address-of-variable(x) -> t2
    store(t1,t2) -> t1
    ignore(t1)               -- because of the ';', the assignment 
                             -- expression is converted into a
                             -- statement, and therefore its value
                             -- is ignored.

In Lisp, the type is associated to the value, not to the
variables. Variables can be bound to values of any type.
The semantics of (setq x 42) will be:
   
   42 -> t1
   get-variable-named(x) -> t2
   bind(t2,t1)
   return(t1) -> t1

In Lisp there are only expressions, if if the assignment expression is
the last of a 'block' (eg. a function) its value will be returned as
the result.  Only if there's a sequence of expressions may the result
of the expression be ignored.  Also, the semantics of variables is not
defined in terms of memory addresses contrarily to C.  The fact that a
value is bound to a variable is not necessarily translated to a memory
store, it's only a 'naming' of the value of an expression.


And I won't even try to make a comparison with stranger languages like
lazy functional languages or logic languages (where some kind of
"assignment" can also be found, but with even more different
semantics).



Also, in the above, I didn't mention the semantics differences that
may occur when x is not a mere variable, but eg. a C macro, or a Lisp
symbol-macro, or if setq is not CL:SETQ but a user defined operator...



Well, if you insist for the anecdote:
    
http://99-bottles-of-beer.net/
http://www.ntecs.de/old-hp/uu9r/lang/html/lang.en.html



> I am now dealing with substring assignment.
>
> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
> has to use n=j-i+1 (length("AB")).
>
> I want an assignment which returns string="aABd"

In Common Lisp:

(let ((i 2) (j 3) (string (copy-seq "abcd")) (value "AB"))
   (replace string value :start1 (1- i) :end1 j)
   string)
--> "aABd"

It can also be written as:

(let ((i 2) (j 3) (string (copy-seq "abcd")) (value "AB"))
    (setf (subseq string (1- i) j) value)
    string)
--> "aABd"


> I started from Fortran string(i:j)=value
>
> I came out with the examples below, but cannot find a satisfactory one
> for C using standard library functions.

Not surprizing, since there's no string in C.  It only knows vectors
of bytes, and pointer to bytes or vectors of bytes. (bytes, ie. 'char'
being a subtype of 'int' (or 'unsigned int')).

Perpetuating the C defect of using char* or char[] for string, we
could implement string_assign as:

#include <stdio.h>
#include <string.h>

char* string_assign(char* destination,size_t start,size_t end,const char* source){
   size_t dlen=strlen(destination);
   size_t slen=strlen(source);
   size_t start1=start-1;
   size_t end1=end-1;
   if(slen<end1-start1){
       end1=start1+slen;
   }
   if(dlen<end1){
       end1=dlen;
   }
   if(start1<dlen){
      strncpy(destination+start1,source,end1-start1+1);
   }
   return(destination);
}

int main(){
   char  destination[]="abcd";
   char* source="AB";
   string_assign(destination,2,3,source);
   printf("%s\n",destination);
   return(0);
}


But it would be better to design an abstract data type to manage
strings.  There are several string libraries for C doing just that.


> IDL: strput,string,value,i
>
> Java: string=string.substring(0,i)+value+string.substring(j+1) ;
>       or using string buffers
>       StringBuffer sb = new StringBuffer(string) ;
>       sb.replace(i,j+1,value) ;
>
> awk: string=substr(string,1,i-1) value substr(a,j+1)
>
> mysql: set @string:=insert(@string,@i,@n,@value)
>
> Postscript: string i value putinterval /string exch def
>
> I even have csh
>
> @ i=$i-1
> @ j=$j+1
> set string=`echo $string | cut -c-$i`$value`echo $string | cut -c$j-`
>
> But what about C ?
> I can find an hardcoded solution for a character array
>
>      char a[5]="abcd" ;
>      a[1]='A';
>      a[2]='B';
>
> which means I can possibly write some for loop
>
> But what if I want a (or string) to be a "standard" string i.e. a
> char *a ?
>
>
> Please note followup to clf

-- 
__Pascal Bourguignon__
0
Reply pjb (7645) 5/20/2009 4:22:34 PM

"LC's No-Spam Newsreading account" <nospam@mi.iasf.cnr.it> wrote in message 
news:alpine.LSU.2.00.0905191841260.31232@cbfrvqba.ynzoengr.vans.vg...
>I am trying to collect equivalent statements in various languages.
>
> I am now dealing with substring assignment.
>
> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't scandalize 
> if in your favourite language it is i=1 j=2 :=). Nor if one has to use 
> n=j-i+1 (length("AB")).
>
> I want an assignment which returns string="aABd"
> [...]
> But what about C ?
> [...]


You can try this out this very crude little program:
_____________________________________________________________________
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>


char*
static_substr_assign_ver1(
 char* str,
 char const* sstr,
 char const* rstr
) {
  char* pos = strstr(str, sstr);
  assert(str && sstr && rstr);
  if (pos) {
    size_t slen = strlen(sstr);
    if (slen) {
      size_t rlen = strlen(rstr);
      if (rlen) {
        if (rlen > slen) {
          rlen = slen;
        }
        memcpy(pos, rstr, rlen);
        return str;
      }
    }
  }
  return NULL;
}


char*
static_substr_assign_ver2(
 char* str,
 char const* rstr,
 size_t si,
 size_t ei
) {
  size_t len = strlen(str);
  assert(str && rstr && si <= len - 1 &&
         ei <= len - 1 && ei >= si);
  if (str + ei < str + len && ei >= si) {
    size_t rlen = strlen(rstr);
    if (rlen) {
      if (rlen > ei - si + 1) {
        rlen = ei - si + 1;
      }
      memcpy(str + si, rstr, rlen);
      return str;
    }
  }
  return NULL;
}


int main(void) {
  char str[] = "xyzm";

  puts(static_substr_assign_ver1(str, "xyz", "Abc"));
  puts(static_substr_assign_ver2(str, "D", 3, 3));
  puts(static_substr_assign_ver2(str, "a", 0, 0));
  puts(static_substr_assign_ver1(str, "D", "d"));
  puts(static_substr_assign_ver2(str, "AB", 1, 2));

  return 0;
}
_____________________________________________________________________




I attempted to put some quick and dirty validity/sanity checks in the 
functions in order to prevent buffer overruns. I quickly typed this in, and 
probably missed something!

;^o 

0
Reply no6 (2791) 5/20/2009 4:53:55 PM

On Wed, 20 May 2009, Pascal J. Bourguignon wrote:
> LC's No-Spam Newsreading account <nospam@mi.iasf.cnr.it> writes:
>
>> I am trying to collect equivalent statements in various languages.
>
> This is rather useless an endeavour.  Anecdotic at most.

Well, what I'm thinking of is sort of the phrase books a traveller in a 
foreign country uses.

It can be useful to somebody (like me) who is fluent in 2-3 languages 
and uses other languages only sometimes,

-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/21/2009 11:55:45 AM

Given that the reason for my attempt 
>> >  to collect equivalent statements in various languages.
was aimed to 
> sort of the phrase books a traveller in a foreign country uses. It can 
> be useful to somebody (like me) who is fluent in 2-3 languages and 
> uses other languages only sometimes,

.... so to write down some "standard idioms" which I can look up in order 
to avoid silly mistakes when using one of the unfamiliar languages.

.... let me see if I can summarize all the helpful hints I've received 
(and archived).

I wanted to collect statements equivalent to Fortran assignment to a 
substring : string(i:j)=value

where all items (string, value, i, j) are variables of the appropriate 
type. I want string to be modified in place ( "abcd" -> "aABd" ), and 
I'm looking for the most compact or most legible form (ideally both) 
which uses native features. I.e. I do not care whether it is an 
assignment or a function call, or even a few statements, but I would 
like NOT to consider an user-written function (unless that's The Only 
Way). Also I do not care at this stage about error handling when strings 
are too long or too short, null padding or blank padding, etc.

Now both the proposed C equivalents listed below match my requirement

     memcpy(string+i, value, j+1-i);
     strncpy(string+i, value, j+1-i);

BUT there is a caveat which I'd like to be confirmed about the way 
"strings" shall be defined in C.

I've even seen people using "typedef char * string;"

I can use declarations like :

  1) char *a
  2) char a[]
  3) char a[somenumber]

I am not at all scandalized by the third form (I'm used since ever to
the Fortran CHARACTER*somenumber A), but I thought that C could have 
"variable-and-dynamic-length" null terminated strings, contrary to the 
more rigid fixed-length strings of Fortran,

Now the point comes to whether I add initialization (DATA statement in 
my Fortran parliance) and assignment.

I could initialize string a adding e.g. ="123456" to the declaration of 
form (1) and (2), but not (3). Also I am OBLIGED to do the 
initialization with the undefined length array notation a[] ( I *must* 
use (2D), while (2) gives compiler error 'array size missing' )

  1D) char *a="123456" ;
  2D) char a[]="123456" ;

If I do not initialize (forms (1) and (3)) I can later assign a value.

But form (1) requires the assignment as a="123456", while form (3) 
requires instead strcpy(a,"123456").

What is more important, the first argument (destination) of strcpy 
cannot be a dynamic length string (1) i.e. char *a ! If it is one gets a 
segmentation fault. It must be a character array (2) or (3).

Otherwise said I cannot declare a string of undefined length as char a[] 
unless I also initialize it (like CHARACTER*(*) valid only for a 
PARAMETER constant in a main).

Is all this correct ?


So the shortest main program which demonstrates my case (where all items 
are variables assigned explicitly a value, not just initialized) is

     int i,j ;
     char a[4] ;                  /* must use a maximum size */
     char *b ;                    /* no size implied */
     strcpy(a,"abcd") ;           /* value assigned later THUS */
     b = "AB" ;                   /* value assigned later THUS */
     printf("a = %s\n", a);
     i=1 ; j=2 ;
     strncpy(a+i,b,j+1-i    ) ;   /* or memcpy */
     printf("a = %s\n", a);


-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/21/2009 3:48:53 PM

nick_keighley_nospam@hotmail.com wrote:
>> I started from Fortran string(i:j)=value
> 
> ...
[snip huge Scheme program]

In OCaml, this is just:

  String.blit

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
0
Reply jon (3267) 5/21/2009 5:57:33 PM

LC's No-Spam Newsreading account wrote:
....
> I've even seen people using "typedef char * string;"

Such typedefs reflect and reinforce the misconception that C has a
string data type. It does not. It does have a string data format, but
you can use many different C constructs to store data in that format.
A char* can be used to point at the first element of a string, but it
is not itself a string.

> I can use declarations like :
>
>   1) char *a
>   2) char a[]
>   3) char a[somenumber]
>
> I am not at all scandalized by the third form (I'm used since ever to
> the Fortran CHARACTER*somenumber A), but I thought that C could have
> "variable-and-dynamic-length" null terminated strings, contrary to the
> more rigid fixed-length strings of Fortran,

The difference between 2) and 3) is entirely in how the fixed length
of the array is determined. They both have a fixed length. They both
can contain strings of any length up to but not including the length
of the array. They are both capable of containing multiple strings,
which is an example of the fact that, in C, "string" is a data format,
not a data type.

> Now the point comes to whether I add initialization (DATA statement in
> my Fortran parliance) and assignment.
>
> I could initialize string a adding e.g. ="123456" to the declaration of
> form (1) and (2), but not (3).

You're incorrect about (3). The definition

     char a[5] = "123456";

would be a constraint violation. However,  the definitions

     char b[6] = "123456";
     char c[7] = "123456";
     char d[8] = "123456";

are all perfectly fine. Note: b does not contain a string, since it
has no terminating null character.

> ... Also I am OBLIGED to do the
> initialization with the undefined length array notation a[] ( I *must*
> use (2D), while (2) gives compiler error 'array size missing' )

That's because it is not an "undefined length array", it's an
implicitly defined length, and without the initializer there's nothing
to implicitly define the length.

>   1D) char *a="123456" ;
>   2D) char a[]="123456" ;
>
> If I do not initialize (forms (1) and (3)) I can later assign a value.

No, only the pointer can be assigned to. You can assign to the
elements of the arrays in case (2) and (3), and by doing so you can
create one or more strings in them. However, this is true whether or
not you initialize them.

> But form (1) requires the assignment as a="123456", while form (3)
> requires instead strcpy(a,"123456").

No, there are many different ways to assign a value to the pointer.
The key point to keep in mind is that declaring a pointer doesn't
initialize any memory for a character string. That has to be done
separately; for instance, using the string literal "123456" causes an
unnamed array to be created to contain the corresponding string, and
using that string literal to initialize a char* variable causes that
variable to be set to point at the the first element of the array. But
that pointer could be set to point at any other char in that array, or
in any other char array, for that matter.

strcpy() is one way to copy a string from one array to another, but
there are many others. It works just as well for (2) as for (3).

> What is more important, the first argument (destination) of strcpy
> cannot be a dynamic length string (1)

Incorrect. If the pointer were set to point at writable memory (which
it currently is not - the arrays created by using string literals are
not safely writeable), strcpy() could also be used to copy the string
into whichever location in memory it is currently pointing at.

> ... i.e. char *a ! If it is one gets a
> segmentation fault. ...

That is true only if it points at a memory segment that you don't
currently have permission to write to. Whether or not this is the case
for the arrays created to store string literals is up to the
implementation, which is why its not safe to assume that you can write
to them.

> ... It must be a character array (2) or (3).
>
> Otherwise said I cannot declare a string of undefined length as char a[]
> unless I also initialize it (like CHARACTER*(*) valid only for a
> PARAMETER constant in a main).
>
> Is all this correct ?

Not really. You've confused the issue by using the same name for all
three cases. Let me distinguish them as follows:

    char *pc = "123456";
    char imp_length[] = "123456";
    char exp_length[7] = "123456";

Any use of the string literal "123456" anywhere in your program causes
at least one unnamed array of char to be created, initialized with the
valued '1', '2', '3', '4', '5', '6', '\0', in that order. It's
entirely up to the implementation whether or not all uses of "123456"
refer to the same array, or whether each such use refers to a
different array. In addition, it's entirely up to the implementation
whether or not the array created for "123456" occupies the same
location in memory as the last seven elements of the array created for
"0123456". The behavior of any program that attempts to write anything
into one of those blocks of memory is undefined.

The variable named pc is a pointer that is initialized to point at the
first character in one of those blocks of memory. It could, at any
later time, be re-set to point at some other piece of memory. The
following statement:

    pc = &imp_length[3] ;

causes pc to point at the char within imp_length which has the value
'4'. Here's where the difference between a data type and a data format
comes into play: &imp_length[n] is itself a pointer to the first
character of a string with a length of 5-n, for any value of n from 0
to 5. All of those strings share the same terminating null character.
five of them share the same '5' character, etc. Until you understand
that statement, you really don't understand what C strings are.

imp_length is an array of 7 characters; the length is determined
implicily by counting the characters in the string literal "123456",
and adding 1 for the terminating null character. That array is filled
in by copying from the array used store the string literal. In this
case, there's no way for your program to even determine whether the
string literal's array actually exists; which means that in some cases
it won't actually exist; the only copy of those characters could be in
imp_length itself. Having been initialized with "123456", you're free
to change the contents of that array; in particular, the statement

     imp_length[3] = '\0';

means that it no longer contains a string of length 6. It now starts
with a string of length 3; and contains another string of length 2
starting at &imp_length[4]. It also contains 5 other strings, but
they're just subsets of those two strings.

exp_length is an array of 7 characters, just like imp_length. They
have different names and different locations, but once defined, they
have the same type and can be used in the same way. The only
difference between them is how the length of the array is determined,
and how it is initialized. If exp_length were initialized with
"12345", there would be two  '\0' characters at the end, rather than
none. If the initializer were "1234567", the '7' would be copied into
the last element of the array, and the array would not contain a
string,  because it would lack the required terminating null character
required for strings. If the initializer were "12345678", it would be
a constraint violation.

> So the shortest main program which demonstrates my case (where all items
> are variables assigned explicitly a value, not just initialized) is
>
>      int i,j ;
>      char a[4] ;                  /* must use a maximum size */
>      char *b ;                    /* no size implied */

Also, no memory allocated for a string, and no value has been assigned
to the pointer. It is therefore NOT safe to use 'b' in any way until
it has been initialized.

>      strcpy(a,"abcd") ;           /* value assigned later THUS */

This copies the first four characters from the array created for the
string literal "abcd" into the array you've defined named 'a'. It then
tries to copy the terminating null character, but finds that there is
no room for it. The behavior of your program is therefore undefined.
In practice, that null character might get written somewhere where it
can cause a great deal of trouble, or it might get written somewhere
completely innocuous. It's also possible that it will not get written,
an event that might or might not cause your program to abort.

>      b = "AB" ;                   /* value assigned later THUS */

This sets b to point at the 'A' character in the array set aside for
the string literal "AB".

>      printf("a = %s\n", a);

Because of the way typical compilers work, if you reach this point in
the code, there's a pretty good chance that this will accidentally
work as you expected it to, despite the erroneous strcpy() call, but
you shouldn't count on it.
0
Reply jameskuyper (5157) 5/21/2009 6:32:10 PM

LC's No-Spam Newsreading account <nospam@mi.iasf.cnr.it> writes:
<snip>
> ... let me see if I can summarize all the helpful hints I've received
> (and archived).
>
> I wanted to collect statements equivalent to Fortran assignment to a
> substring : string(i:j)=value
>
> where all items (string, value, i, j) are variables of the appropriate
> type. I want string to be modified in place ( "abcd" -> "aABd" ), and
> I'm looking for the most compact or most legible form (ideally both)
> which uses native features. I.e. I do not care whether it is an
> assignment or a function call, or even a few statements, but I would
> like NOT to consider an user-written function (unless that's The Only
> Way). Also I do not care at this stage about error handling when
> strings are too long or too short, null padding or blank padding, etc.
>
> Now both the proposed C equivalents listed below match my requirement
>
>     memcpy(string+i, value, j+1-i);
>     strncpy(string+i, value, j+1-i);
>
> BUT there is a caveat which I'd like to be confirmed about the way
> "strings" shall be defined in C.

It's a big one.  This is no string type in C.  A string is data format
in an array.

> I've even seen people using "typedef char * string;"
>
> I can use declarations like :
>
>  1) char *a
>  2) char a[]
>  3) char a[somenumber]

None of these are strings, of course.

> I am not at all scandalized by the third form (I'm used since ever to
> the Fortran CHARACTER*somenumber A), but I thought that C could have
> "variable-and-dynamic-length" null terminated strings, contrary to the
> more rigid fixed-length strings of Fortran,
>
> Now the point comes to whether I add initialization (DATA statement in
> my Fortran parliance) and assignment.
>
> I could initialize string a adding e.g. ="123456" to the declaration
> of form (1) and (2), but not (3).

You can do that for (3) as well.  If somenumber is > 6 (not <= 6) then
you get a string in the array -- it will be null terminated.  If there
is no room for the null you get a character array filled with
characters rather than a string.

> Also I am OBLIGED to do the
> initialization with the undefined length array notation a[] ( I *must*
> use (2D), while (2) gives compiler error 'array size missing' )
>
>  1D) char *a="123456" ;
>  2D) char a[]="123456" ;
>
> If I do not initialize (forms (1) and (3)) I can later assign a
> value.

Hmm...  Not in case (3).  Assignment means using = and arrays can't be
assigned.  Some people talk of strcpy(a, "123") as assigning a string
to the array, but that is loose talk at best.  It is just the wrong
word.

> But form (1) requires the assignment as a="123456", while form (3)
> requires instead strcpy(a,"123456").

Oh, you're one of them!  Sorry.  No, don't call it that.  You are
copying a string form one place to another.

> What is more important, the first argument (destination) of strcpy
> cannot be a dynamic length string (1) i.e. char *a ! If it is one gets
> a segmentation fault. It must be a character array (2) or (3).

No.  char *a; just declared the variable 'a' to be a pointer to some
space.  Until you assign it (yes, real assignment) it does not point
to any valid address (technically the pointer is indeterminate).  To
use dynamic strings, you have to do all the allocation yourself.  For
example, to copy b to a:

  a = malloc(strlen(b) + 1);
  if (a)
       strcpy(a, b);

> Otherwise said I cannot declare a string of undefined length as char
> a[] unless I also initialize it (like CHARACTER*(*) valid only for a
> PARAMETER constant in a main).

The trouble is, as I said, there is no string type.  C operates at a
lower level than this.  You can declare character arrays and, if you
are careful, you can ensure they always contains valid strings; but it
is your job to do all the work.

> Is all this correct ?

Not as bad as it seems from my comments.

> So the shortest main program which demonstrates my case (where all
> items are variables assigned explicitly a value, not just initialized)
> is
>
>     int i,j ;
>     char a[4] ;                  /* must use a maximum size */
>     char *b ;                    /* no size implied */
>     strcpy(a,"abcd") ;           /* value assigned later THUS */

BANG!  This copies 5 bytes from the literal string to a.  You have
space for 4.  I'd have written:

      char a[] = "abcd";

but you wanted to illustrate strcpy, I know.

>     b = "AB" ;                   /* value assigned later THUS */
>     printf("a = %s\n", a);
>     i=1 ; j=2 ;
>     strncpy(a+i,b,j+1-i    ) ;   /* or memcpy */
>     printf("a = %s\n", a);

-- 
Ben.
0
Reply ben.usenet (6515) 5/21/2009 7:02:52 PM

In comp.lang.fortran Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
 
<> Also I am OBLIGED to do the
<> initialization with the undefined length array notation a[] ( I *must*
<> use (2D), while (2) gives compiler error 'array size missing' )

<>  1D) char *a="123456" ;
<>  2D) char a[]="123456" ;

In case comp.lang.fortran readers are not familiar with this, it
dimensions a of the correct size to hold the initialization, where
"123456" is short for {'1','2','3','4','5','6',0}, and can be
used for initialized arrays of any type.  As I have heard, computers
are better at counting than people, and requiring one to get the
right dimension for the appropriate number of initialization values
does not help the programmer.   Does Fortran have a way to dimension
an array of the appropriate length for its initial value?

<> If I do not initialize (forms (1) and (3)) I can later assign a
<> value.
 
< Hmm...  Not in case (3).  Assignment means using = and arrays can't be
< assigned.  Some people talk of strcpy(a, "123") as assigning a string
< to the array, but that is loose talk at best.  It is just the wrong
< word.
 
<> But form (1) requires the assignment as a="123456", while form (3)
<> requires instead strcpy(a,"123456").

< Oh, you're one of them!  Sorry.  No, don't call it that.  You are
< copying a string form one place to another.

Are you disqualifying it because of function notation, or because
it is a function call?  Compilers may implement it inline, and
Fortran CHARACTER assignment may be implemented internally
as a function call.  Yes it is different, but not that different.

Does  a="123456"  in Fortran "copy" a string?
 
<> What is more important, the first argument (destination) of strcpy
<> cannot be a dynamic length string (1) i.e. char *a ! If it is one gets
<> a segmentation fault. It must be a character array (2) or (3).
 
< No.  char *a; just declared the variable 'a' to be a pointer to some
< space.  Until you assign it (yes, real assignment) it does not point
< to any valid address (technically the pointer is indeterminate).  To
< use dynamic strings, you have to do all the allocation yourself.  For
< example, to copy b to a:
 
<  a = malloc(strlen(b) + 1);
<  if (a)
<       strcpy(a, b);
 
<> Otherwise said I cannot declare a string of undefined length as char
<> a[] unless I also initialize it (like CHARACTER*(*) valid only for a
<> PARAMETER constant in a main).

As has been said, this does not generate an array of undefined
length, it has the appropriate length for its initial value.

C doesn't have SIZE, but you can use sizeof() to determine
the size, which is a compile time constant.  (sizeof(a)/sizeof(*a))
 
0
Reply gah (12253) 5/21/2009 8:30:59 PM

On 2009-05-21 16:30:59 -0400, glen herrmannsfeldt <gah@ugcs.caltech.edu> said:

>   Does Fortran have a way to dimension
> an array of the appropriate length for its initial value?

character( len= *), parameter :: name = 'value'

As of f08, array constants may be set to the correct size
for their initial value.

Allocatable arrays are set to the correct size automatically
on assignment.

-- 
Cheers!

Dan Nagle

0
Reply dannagle (1019) 5/21/2009 8:51:30 PM

glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> In comp.lang.fortran Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
[...]
> < Hmm...  Not in case (3).  Assignment means using = and arrays can't be
> < assigned.  Some people talk of strcpy(a, "123") as assigning a string
> < to the array, but that is loose talk at best.  It is just the wrong
> < word.
>  
> <> But form (1) requires the assignment as a="123456", while form (3)
> <> requires instead strcpy(a,"123456").
>
> < Oh, you're one of them!  Sorry.  No, don't call it that.  You are
> < copying a string form one place to another.
>
> Are you disqualifying it because of function notation, or because
> it is a function call?  Compilers may implement it inline, and
> Fortran CHARACTER assignment may be implemented internally
> as a function call.  Yes it is different, but not that different.

Sure, but C defines the term "assignment", and it's the thing
specified by an assignment operator.

> Does  a="123456"  in Fortran "copy" a string?

I don't know, does it?  In C, it would copy the address of the
string's first character, not the string itself.

[...]

> <  a = malloc(strlen(b) + 1);
> <  if (a)
> <       strcpy(a, b);
>  
> <> Otherwise said I cannot declare a string of undefined length as char
> <> a[] unless I also initialize it (like CHARACTER*(*) valid only for a
> <> PARAMETER constant in a main).
>
> As has been said, this does not generate an array of undefined
> length, it has the appropriate length for its initial value.
>
> C doesn't have SIZE, but you can use sizeof() to determine
> the size, which is a compile time constant.  (sizeof(a)/sizeof(*a))

That works if a is declared as an array, but in this case it's a
pointer object, and (sizeof(a)/sizeof(*a)) won't give you anything
meaningful.

C arrays are very commonly manipulated by passing pointers around,
e.g., as function arguments.  When you do this, you have to have some
other way to determine the array's length.  You can either pass the
length as a separate argument, or you can use strlen() to search for
the trailing '\0' if the array happens to contain a string (note that
the length of the string and the size of the array that contains it
are not the same thing).

I guess that Fortran treats arrays more like first-class objects, but
I'm not at all familiar with Fortran.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 5/21/2009 9:14:20 PM

glen herrmannsfeldt wrote:
> In comp.lang.fortran Ben Bacarisse <ben.usenet@bsb.me.uk> wrote:
....
> < Hmm...  Not in case (3).  Assignment means using = and arrays can't be
> < assigned.  Some people talk of strcpy(a, "123") as assigning a string
> < to the array, but that is loose talk at best.  It is just the wrong
> < word.
>
> <> But form (1) requires the assignment as a="123456", while form (3)
> <> requires instead strcpy(a,"123456").
>
> < Oh, you're one of them!  Sorry.  No, don't call it that.  You are
> < copying a string form one place to another.
>
> Are you disqualifying it because of function notation, or because
> it is a function call?  Compilers may implement it inline, and
> Fortran CHARACTER assignment may be implemented internally
> as a function call.  Yes it is different, but not that different.

The C standard clearly distinguishes between assignment expressions
and function call expressions. Neither term has any meaning in C that
does not involve such expressions, and it's never ambiguous whether a
given expression is an assignment expression or a function call
expression. The distinction might be blurred in some other contexts,
but not in C.

What happens internally might be that a function call expression
actually gets inlined, or that an assignment expression is converted
into a function call, but since that's all up to the implementation,
it's not really meaningful to even talk about it without first
specifying which particular implementation of C you're referring to.
It is important to know which type of expression you're talking about,
because what you can do with the expression is quite different in the
two cases.

> Does  a="123456"  in Fortran "copy" a string?

I don't know. In C,

     char word[] = "hello";
     char pa = word;
     strcpy(pa, "world", sizeof "world");
     pa = "other";

The third line contains a strcpy() call that copies the array set
aside for the string literal "world", into the array named 'word'. The
last statement, on the other hand, contains an assignment expression
that changes pa so that it no longer points at 'word', it instead
points at the unnamed array set aside for the string literal "other".
Which of those two statements is most similar to what the Fortran
statement does? Or is it perhaps meaningless to even compare them?

....
> C doesn't have SIZE, but you can use sizeof() to determine
> the size, which is a compile time constant.  (sizeof(a)/sizeof(*a)).

Not in C99. The following is legal C99 code, where the value of a
sizeof expression cannot, in general, be determined at compile time:

size_t func(int n)
{
     char vla_array[n];
     return sizeof vla_array;
}

Keep in mind that while sizeof gives the size of the array, it is
strlen() which gives the length of the string stored in that array.
That length must be shorter than the length of the array by at least 1
(for the terminating null character), unless the array doesn't contain
a string, in which case calling strlen() has undefined behavior.

0
Reply jameskuyper (5157) 5/21/2009 9:30:54 PM

In comp.lang.fortran Dan Nagle <dannagle@verizon.net> wrote:
(I wrote)
 
<>   Does Fortran have a way to dimension
<> an array of the appropriate length for its initial value?
 
< character( len= *), parameter :: name = 'value'
 
< As of f08, array constants may be set to the correct size
< for their initial value.

Well, the question was for arrays, though in C strings are arrays.

C has:

   int i[]={1,2,3,4,5};

which will dimension i to 5 and initialize it.  I believe this
would be somthing like:

  integer i(*)=(/ 1,2,3,4,5,/)

which I don't believe is legal as of Fortran 2003.

C also has:

   int i[][3]={{1,2,3},{4,5,6}};

(Only the leftmost can be left out.)
 
< Allocatable arrays are set to the correct size automatically
< on assignment.

Yes, but that is a different question.

-- glen
 
0
Reply gah (12253) 5/21/2009 9:43:41 PM

In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
(snip, I wrote)

<> Are you disqualifying it because of function notation, or because
<> it is a function call?  Compilers may implement it inline, and
<> Fortran CHARACTER assignment may be implemented internally
<> as a function call.  Yes it is different, but not that different.
 
< The C standard clearly distinguishes between assignment expressions
< and function call expressions. Neither term has any meaning in C that
< does not involve such expressions, and it's never ambiguous whether a
< given expression is an assignment expression or a function call
< expression. The distinction might be blurred in some other contexts,
< but not in C.

I completely agree.  But if you ask how to do the equivalent of
the Fortran assignment:

    c="hi there"

in C, and one answers with

   strcpy(c,"hi there");

then it isn't fair to disqualify it as being a function call.
It performs the same operation but has a different name.
 
< What happens internally might be that a function call expression
< actually gets inlined, or that an assignment expression is converted
< into a function call, but since that's all up to the implementation,
< it's not really meaningful to even talk about it without first
< specifying which particular implementation of C you're referring to.
< It is important to know which type of expression you're talking about,
< because what you can do with the expression is quite different in the
< two cases.
 
<> Does  a="123456"  in Fortran "copy" a string?
 
< I don't know. In C,
 
(snip, then I wrote)

<> C doesn't have SIZE, but you can use sizeof() to determine
<> the size, which is a compile time constant.  (sizeof(a)/sizeof(*a)).
 
< Not in C99. The following is legal C99 code, where the value of a
< sizeof expression cannot, in general, be determined at compile time:
 
< size_t func(int n)
< {
<     char vla_array[n];
<     return sizeof vla_array;
< }

Well, I meant specifically for the case of initialized arrays
that otherwise are of unknown length.  If instead you do:

 size_t func(int n)
 {
     int vla_array[n];
     return sizeof vla_array/sizeof(int);
 }

Would you expect a run time divide to be done?  (Not that divide
is so slow on modern computers, but still one might want to know.)
 
< Keep in mind that while sizeof gives the size of the array, it is
< strlen() which gives the length of the string stored in that array.
< That length must be shorter than the length of the array by at least 1
< (for the terminating null character), unless the array doesn't contain
< a string, in which case calling strlen() has undefined behavior.

I meant it in the general array sense, where the terminating null
doesn't appear.  There is no need to divide by sizeof(char) in
the character case.  If one did

   int i[]={1,2,3};

then using sizeof() is the only way to determine the actual size,
unless the length is hard coded, which removes the advantage of
this notation.  (Well, one could code a special last value even
in the int case.)

-- glen
 
0
Reply gah (12253) 5/21/2009 10:01:55 PM

"jameskuyper" <jameskuyper@verizon.net> wrote in message 
news:d9fe8456-9e58-4df0-931b-6036c80689b6@g37g2000yqn.googlegroups.com...
> glen herrmannsfeldt wrote:
>> Does  a="123456"  in Fortran "copy" a string?
>
> I don't know. In C,
>
>     char word[] = "hello";
>     char pa = word;
>     strcpy(pa, "world", sizeof "world");
>     pa = "other";

It makes a bit more sense like this:

     char word[] = "hello";
     char *pa = word;
     memcpy(pa, "world", sizeof "world");
     pa = "other";

Or perhaps with the copy line like this:

     strcpy(pa, "world");

But either way it would go wrong if the "world" string was longer than the 
"hello" string.

-- 
Bart


0
Reply bartc (783) 5/21/2009 10:16:20 PM

glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
> (snip, I wrote)
>
> <> Are you disqualifying it because of function notation, or because
> <> it is a function call?  Compilers may implement it inline, and
> <> Fortran CHARACTER assignment may be implemented internally
> <> as a function call.  Yes it is different, but not that different.
>  
> < The C standard clearly distinguishes between assignment expressions
> < and function call expressions. Neither term has any meaning in C that
> < does not involve such expressions, and it's never ambiguous whether a
> < given expression is an assignment expression or a function call
> < expression. The distinction might be blurred in some other contexts,
> < but not in C.
>
> I completely agree.  But if you ask how to do the equivalent of
> the Fortran assignment:
>
>     c="hi there"
>
> in C, and one answers with
>
>    strcpy(c,"hi there");
>
> then it isn't fair to disqualify it as being a function call.
> It performs the same operation but has a different name.

I don't think anyone intended to "disqualify" it.  If the Fortran
    c="hi there"
means the same thing as C's
    strcpy(c,"hi there")
then yes, it's the equivalent.  The C function call just isn't an
assignment.

That's actually a fairly important point: C's equivalent of that
particular Fortran assignment statement is a function call, not an
assignment.

[...]

> Well, I meant specifically for the case of initialized arrays
> that otherwise are of unknown length.  If instead you do:
>
>  size_t func(int n)
>  {
>      int vla_array[n];
>      return sizeof vla_array/sizeof(int);
>  }
>
> Would you expect a run time divide to be done?  (Not that divide
> is so slow on modern computers, but still one might want to know.)

Probably.  Actually sizeof(int) is likely to be a power of 2, so the
division is likely to be replaced by a shift.

It's also possible that a compiler might be clever enough to notice
that sizeof vla_array is the length of the array times sizeof(int),
and optimize it to the equivalent of "return n;".  Note that the
length of the array is the value of n when the declaration is reached,
so the compiler also has to allow for the possibility that n has
changed.  (It will probably just save the value somewhere.)

> < Keep in mind that while sizeof gives the size of the array, it is
> < strlen() which gives the length of the string stored in that array.
> < That length must be shorter than the length of the array by at least 1
> < (for the terminating null character), unless the array doesn't contain
> < a string, in which case calling strlen() has undefined behavior.
>
> I meant it in the general array sense, where the terminating null
> doesn't appear.  There is no need to divide by sizeof(char) in
> the character case.  If one did
>
>    int i[]={1,2,3};
>
> then using sizeof() is the only way to determine the actual size,
> unless the length is hard coded, which removes the advantage of
> this notation.  (Well, one could code a special last value even
> in the int case.)

Right, but in C there's always the danger of confusing arrays and
pointers.  A parameter declared to be of an array type is really a
pointer, and applying sizeof to it will just give you the size of the
pointer.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 5/21/2009 10:16:59 PM

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message 
news:gv4j0j$4e2$2@naig.caltech.edu...
> In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
> (snip, I wrote)
>
> <> Are you disqualifying it because of function notation, or because
> <> it is a function call?  Compilers may implement it inline, and
> <> Fortran CHARACTER assignment may be implemented internally
> <> as a function call.  Yes it is different, but not that different.
.....
> I completely agree.  But if you ask how to do the equivalent of
> the Fortran assignment:
>
>    c="hi there"
>
> in C, and one answers with
>
>   strcpy(c,"hi there");
>
> then it isn't fair to disqualify it as being a function call.
> It performs the same operation but has a different name.

It means it isn't really built-in to the language.

If you used a language that required function calls for everything: 
assign(), add(), mul(), equal(), and so on, then you might come to a similar 
conclusion. Even if a particularly clever compiler managed to inline these 
function calls...

Apart from the anomaly of structs, the core language of C only likes pushing 
around bytes and machine words. Anything more high level needs to be 
explicitly built on top of that.

-- 
Bart 

0
Reply bartc (783) 5/21/2009 10:27:13 PM

In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
(snip, I wrote)

<> I meant it in the general array sense, where the terminating null
<> doesn't appear.  There is no need to divide by sizeof(char) in
<> the character case.  If one did

<>    int i[]={1,2,3};

<> then using sizeof() is the only way to determine the actual size,
<> unless the length is hard coded, which removes the advantage of
<> this notation.  (Well, one could code a special last value even
<> in the int case.)
 
< Right, but in C there's always the danger of confusing arrays and
< pointers.  A parameter declared to be of an array type is really a
< pointer, and applying sizeof to it will just give you the size of the
< pointer.

Hopefully new C programmers learn this pretty fast, but yes.

Though I don't know that it is any worse than the tricks
used with assumed size arrays in Fortran.  In the Fortran 66 days
it was common to dimension the dummy array (1), and to compute
the appropriate offset, even for a multidimension actual argument.

Later, the (*) notation was added.  C code like:

int x[20];
sub(x+10,10);

can be done in Fortran with assumed size arrays as:

      integer x(20)
      call sub(x(11),10)

where, as with C, the appropriate length should be passed 
unless it is otherwise known to the callee.

-- glen
0
Reply gah (12253) 5/21/2009 10:35:21 PM

"Jon Harrop" <jon@ffconsultancy.com> wrote in message 
news:-_ednbN6WbwQCYjXnZ2dnUVZ8ixi4p2d@brightview.co.uk...
> nick_keighley_nospam@hotmail.com wrote:
>>> I started from Fortran string(i:j)=value
>>
>> ...
> [snip huge Scheme program]
>
> In OCaml, this is just:
>
>  String.blit

I have a language where it is just:

 :=
 :-)

-- 
Bart 

0
Reply bartc (783) 5/21/2009 10:37:39 PM

In comp.lang.fortran BartC <bartc@freeuk.com> wrote:
 
(snip, I wrote)

<> I completely agree.  But if you ask how to do the equivalent of
<> the Fortran assignment:

<>    c="hi there"

<> in C, and one answers with

<>   strcpy(c,"hi there");

<> then it isn't fair to disqualify it as being a function call.
<> It performs the same operation but has a different name.
 
< It means it isn't really built-in to the language.

The question about the C library being part of the language,
or "built in" comes up pretty often.  So SQRT is not really
built into Fortran since it is a function call?  Since the
addition of generic intrinsic functions it is hard to say that
it isn't.   In the C case, strcpy() is "built in" enough that
you might get surprised coding your own function with that name.
 
< If you used a language that required function calls for everything: 
< assign(), add(), mul(), equal(), and so on, then you might come 
< to a similar conclusion. Even if a particularly clever compiler 
< managed to inline these function calls...

In Mathematica everything is a function (if not a function call),
but there are shortcuts.  A+B is a short way to write Add[A,B]
but internally it is the same.
 
< Apart from the anomaly of structs, the core language of C 
< only likes pushing around bytes and machine words. 
< Anything more high level needs to be explicitly built on top 
< of that.

#include <stdio.h>
int main() {
struct {
   int x[10];
   } a,b;
memset(&b,0,sizeof(b));
a=b;
printf("%d\n",a.x[3]);
}

Funny thing in C.  You can't assign arrays, but you can assign
structures, even ones that contain arrays.

Somewhat similar to Fortran, with no arrays of pointers, but
arrays of structures containing pointers exist.

-- glen


 
0
Reply gah (12253) 5/21/2009 10:54:49 PM

glen herrmannsfeldt wrote:
> In comp.lang.fortran jameskuyper <jameskuyper@verizon.net> wrote:
> (snip, I wrote)
....
> < The C standard clearly distinguishes between assignment expressions
> < and function call expressions. Neither term has any meaning in C that
> < does not involve such expressions, and it's never ambiguous whether a
> < given expression is an assignment expression or a function call
> < expression. The distinction might be blurred in some other contexts,
> < but not in C.
>
> I completely agree.  But if you ask how to do the equivalent of
> the Fortran assignment:
>
>     c="hi there"
>
> in C, and one answers with
>
>    strcpy(c,"hi there");
>
> then it isn't fair to disqualify it as being a function call.
> It performs the same operation but has a different name.

In C, c="hi there" and strcpy(c, "hi there") never perform the same
operation. if c has a pointer type, they perform two very different
operations, and only the first one is an assignment. If c has an array
type, c="hi there" is a constraint violation, and strcpy(c, "hi
there") does yet a third thing, not quite the same as either of the
operations involving the pointer. I'm not sure whether any of those
things is really equivalent to what Fortran does.

....
> <> C doesn't have SIZE, but you can use sizeof() to determine
> <> the size, which is a compile time constant.  (sizeof(a)/sizeof(*a)).
>
> < Not in C99. The following is legal C99 code, where the value of a
> < sizeof expression cannot, in general, be determined at compile time:
>
> < size_t func(int n)
> < {
> <     char vla_array[n];
> <     return sizeof vla_array;
> < }
>
> Well, I meant specifically for the case of initialized arrays
> that otherwise are of unknown length.  ...

In context, I thought you were making a comment about sizeof in
general.

> ...If instead you do:
>
>  size_t func(int n)
>  {
>      int vla_array[n];
>      return sizeof vla_array/sizeof(int);
>  }
>
> Would you expect a run time divide to be done?  (Not that divide
> is so slow on modern computers, but still one might want to know.)

I'd expect a decent compiler to optimize that to the equivalent of

    size_t func(int n) { return n;}
0
Reply jameskuyper (5157) 5/21/2009 11:03:52 PM

glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
[...]
> < Right, but in C there's always the danger of confusing arrays and
> < pointers.  A parameter declared to be of an array type is really a
> < pointer, and applying sizeof to it will just give you the size of the
> < pointer.
>
> Hopefully new C programmers learn this pretty fast, but yes.
[...]

In an ideal world they learn it pretty fast.  Unfortunately ...

Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>, does a good
job of clearing up the confusion.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 5/21/2009 11:05:18 PM

On May 21, 11:32 am, jameskuyper <jameskuy...@verizon.net> wrote:
> LC's No-Spam Newsreading account wrote:
> ...
>
> > I've even seen people using "typedef char * string;"
>
> Such typedefs reflect and reinforce the misconception that C has a
> string data type. It does not. It does have a string data format, but
> you can use many different C constructs to store data in that format.
> A char* can be used to point at the first element of a string, but it
> is not itself a string.
>
> > I can use declarations like :
>
> >   1) char *a
> >   2) char a[]
> >   3) char a[somenumber]
>
> > I am not at all scandalized by the third form (I'm used since ever to
> > the Fortran CHARACTER*somenumber A), but I thought that C could have
> > "variable-and-dynamic-length" null terminated strings, contrary to the
> > more rigid fixed-length strings of Fortran,
>
> The difference between 2) and 3) is entirely in how the fixed length
> of the array is determined. They both have a fixed length. They both
> can contain strings of any length up to but not including the length
> of the array. They are both capable of containing multiple strings,
> which is an example of the fact that, in C, "string" is a data format,
> not a data type.
>
> > Now the point comes to whether I add initialization (DATA statement in
> > my Fortran parliance) and assignment.
>
> > I could initialize string a adding e.g. ="123456" to the declaration of
> > form (1) and (2), but not (3).
>
> You're incorrect about (3). The definition
>
>      char a[5] = "123456";
>
> would be a constraint violation. However,  the definitions
>
>      char b[6] = "123456";
>      char c[7] = "123456";
>      char d[8] = "123456";
>
> are all perfectly fine. Note: b does not contain a string, since it
> has no terminating null character.
>
> > ... Also I am OBLIGED to do the
> > initialization with the undefined length array notation a[] ( I *must*
> > use (2D), while (2) gives compiler error 'array size missing' )
>
> That's because it is not an "undefined length array", it's an
> implicitly defined length, and without the initializer there's nothing
> to implicitly define the length.
>
> >   1D) char *a="123456" ;
> >   2D) char a[]="123456" ;
>
> > If I do not initialize (forms (1) and (3)) I can later assign a value.
>
> No, only the pointer can be assigned to. You can assign to the
> elements of the arrays in case (2) and (3), and by doing so you can
> create one or more strings in them. However, this is true whether or
> not you initialize them.
>
> > But form (1) requires the assignment as a="123456", while form (3)
> > requires instead strcpy(a,"123456").
>
> No, there are many different ways to assign a value to the pointer.
> The key point to keep in mind is that declaring a pointer doesn't
> initialize any memory for a character string. That has to be done
> separately; for instance, using the string literal "123456" causes an
> unnamed array to be created to contain the corresponding string, and
> using that string literal to initialize a char* variable causes that
> variable to be set to point at the the first element of the array. But
> that pointer could be set to point at any other char in that array, or
> in any other char array, for that matter.
>
> strcpy() is one way to copy a string from one array to another, but
> there are many others. It works just as well for (2) as for (3).
>
> > What is more important, the first argument (destination) of strcpy
> > cannot be a dynamic length string (1)
>
> Incorrect. If the pointer were set to point at writable memory (which
> it currently is not - the arrays created by using string literals are
> not safely writeable), strcpy() could also be used to copy the string
> into whichever location in memory it is currently pointing at.
>
> > ... i.e. char *a ! If it is one gets a
> > segmentation fault. ...
>
> That is true only if it points at a memory segment that you don't
> currently have permission to write to. Whether or not this is the case
> for the arrays created to store string literals is up to the
> implementation, which is why its not safe to assume that you can write
> to them.
>
> > ... It must be a character array (2) or (3).
>
> > Otherwise said I cannot declare a string of undefined length as char a[]
> > unless I also initialize it (like CHARACTER*(*) valid only for a
> > PARAMETER constant in a main).
>
> > Is all this correct ?
>
> Not really. You've confused the issue by using the same name for all
> three cases. Let me distinguish them as follows:
>
>     char *pc = "123456";
>     char imp_length[] = "123456";
>     char exp_length[7] = "123456";
>
> Any use of the string literal "123456" anywhere in your program causes
> at least one unnamed array of char to be created, initialized with the
> valued '1', '2', '3', '4', '5', '6', '\0', in that order. It's
> entirely up to the implementation whether or not all uses of "123456"
> refer to the same array, or whether each such use refers to a
> different array. In addition, it's entirely up to the implementation
> whether or not the array created for "123456" occupies the same
> location in memory as the last seven elements of the array created for
> "0123456". The behavior of any program that attempts to write anything
> into one of those blocks of memory is undefined.
>
> The variable named pc is a pointer that is initialized to point at the
> first character in one of those blocks of memory. It could, at any
> later time, be re-set to point at some other piece of memory. The
> following statement:
>
>     pc = &imp_length[3] ;
>
> causes pc to point at the char within imp_length which has the value
> '4'. Here's where the difference between a data type and a data format
> comes into play: &imp_length[n] is itself a pointer to the first
> character of a string with a length of 5-n, for any value of n from 0
> to 5. All of those strings share the same terminating null character.
> five of them share the same '5' character, etc. Until you understand
> that statement, you really don't understand what C strings are.
>

I don't see how &imp_len(n) have the same terminating null character
and how all 5 of them share the same '5 character.

> imp_length is an array of 7 characters; the length is determined
> implicily by counting the characters in the string literal "123456",
> and adding 1 for the terminating null character. That array is filled
> in by copying from the array used store the string literal. In this
> case, there's no way for your program to even determine whether the
> string literal's array actually exists; which means that in some cases
> it won't actually exist; the only copy of those characters could be in
> imp_length itself. Having been initialized with "123456", you're free
> to change the contents of that array; in particular, the statement
>
>      imp_length[3] = '\0';
>
> means that it no longer contains a string of length 6. It now starts
> with a string of length 3; and contains another string of length 2
> starting at &imp_length[4]. It also contains 5 other strings, but
> they're just subsets of those two strings.
>

I also don't see how this contains another string of length two
starting at &imp_length[4].
0
Reply cdalten (976) 5/21/2009 11:11:56 PM

In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>> In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:

>> < Right, but in C there's always the danger of confusing 
>> < arrays and pointers.  A parameter declared to be of an 
>> < array type is really a pointer, and applying sizeof to it 
>> < will just give you the size of the pointer.

>> Hopefully new C programmers learn this pretty fast, but yes.
> [...]
> 
> In an ideal world they learn it pretty fast.  Unfortunately ...

I was doing assembly programming years before I learned C,
which made it pretty easy to understand pointers.  I suppose
it is harder if you don't understand addresses.

-- glen
0
Reply gah (12253) 5/22/2009 1:02:10 AM

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:gv4dm3$2o6$1@naig.caltech.edu...

> Does  a="123456"  in Fortran "copy" a string?

It's an ordinary character assignment.


0
Reply robin_v (2738) 5/22/2009 3:35:33 AM

In article <lnmy969hw1.fsf@nuthaus.mib.org>,
Keith Thompson  <kst-u@mib.org> wrote:
>glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>> In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
>[...]
>> < Right, but in C there's always the danger of confusing arrays and
>> < pointers.  A parameter declared to be of an array type is really a
>> < pointer, and applying sizeof to it will just give you the size of the
>> < pointer.
>>
>> Hopefully new C programmers learn this pretty fast, but yes.
>[...]
>
>In an ideal world they learn it pretty fast.  Unfortunately ...
>
>Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>, does a good
>job of clearing up the confusion.

Don't bet on it.  You do know that it isn't actually specified by
the C standard, don't you?  I am not denigrating that FAQ, so much
as pointing out the term "clearing up the confusion" is misleading!

Firstly, the conversion rules between arrays and pointers and back
again allow for indefinite and infinite implicit recursion - the
consensus is that this is a constraint on the implementation to
ensure that they are equivalent, but it's not even hinted at in any
wording.  It isn't visible in C as such, but becomes so as soon as
you extend it (e.g. by adding safe pointers, garbage collection,
OpenMP-style parallelism etc.)

Secondly, the wording of 6.3.2.1#3 is seriously ambiguous about
WHEN the conversion takes place, and there are certain reasonable
interpretations that provide visible differences.  During the early
years of C89 implementations, several of them varied in how they
implemented array arguments.  This was one of the many ignored NB
comments on either C89 or C99.  Please ask for examples, if you want.


Glen can be excused for thinking that the array/pointer mess is not
much worse than the Fortran assumed size and array element to array
one, because you need to have been deeply into the C standard to
know just how bad it is in ISO C.  K&R C was much cleaner.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/22/2009 7:55:49 AM

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:gv4m3p$5qc$3@naig.caltech.edu...
> In comp.lang.fortran BartC <bartc@freeuk.com> wrote:
>
> (snip, I wrote)
>
> <> I completely agree.  But if you ask how to do the equivalent of
> <> the Fortran assignment:
>
> <>    c="hi there"
>
> <> in C, and one answers with
>
> <>   strcpy(c,"hi there");
>
> <> then it isn't fair to disqualify it as being a function call.
> <> It performs the same operation but has a different name.
>
> < It means it isn't really built-in to the language.
>
> The question about the C library being part of the language,
> or "built in" comes up pretty often.  So SQRT is not really
> built into Fortran since it is a function call?  Since the
> addition of generic intrinsic functions it is hard to say that
> it isn't.   In the C case, strcpy() is "built in" enough that
> you might get surprised coding your own function with that name.

I don't know how Fortran works it, but C specifically likes to say sqrt()
etc work like ordinary user functions, even though compilers secretly know
about them. To make sure sqrt() etc are generally available, they are
included in the standard environment.

Sometimes it's just a syntax choice: sqrt can look like "sqrt()" and be
actually built-in (in languages I create, sqrt is actually an operator).

Built-in functions (or operators that look like functions) can also have 
some extra magic that allow them to work on several different types; in C 
that usally isn't possible for user-functions.

> < If you used a language that required function calls for everything:
> < assign(), add(), mul(), equal(), and so on, then you might come
> < to a similar conclusion.

> In Mathematica everything is a function (if not a function call),
> but there are shortcuts.  A+B is a short way to write Add[A,B]
> but internally it is the same.

That's another way of doing things. Perhaps Mathematica also allows all
sorts of special symbols (such as a proper square root sign for sqrt) so
needs alphanumeric alternatives, and Add[] is there for completeness.

> < Apart from the anomaly of structs, the core language of C
> < only likes pushing around bytes and machine words.
> < Anything more high level needs to be explicitly built on top
> < of that.
>
> #include <stdio.h>
> int main() {
> struct {
>   int x[10];
>   } a,b;
> memset(&b,0,sizeof(b));
> a=b;
> printf("%d\n",a.x[3]);
> }
>
> Funny thing in C.  You can't assign arrays, but you can assign
> structures, even ones that contain arrays.

Add a hundred more funny things, and you have a pretty good picture of C...

-- 
bart

0
Reply bartc (783) 5/22/2009 9:48:46 AM

In article <2yuRl.32270$OO7.5450@text.news.virginmedia.com>,
BartC <bartc@freeuk.com> wrote:
>
>I don't know how Fortran works it, but C specifically likes to say sqrt()
>etc work like ordinary user functions, even though compilers secretly know
>about them. To make sure sqrt() etc are generally available, they are
>included in the standard environment.

Not quite.  The functions ARE ordinary functions, but may be wrapped
by macros, which need not call an ordinary function.  The only special
thing about sqrt, as a function, is that it may not be replaced by
the user even if <math.h> is not used.

This was more-or-less true in Fortran 66, completely changed (rather
ambiguously) Fortran 77, and specified properly in Fortran 90.  You
can now use SOME intrinsic procedures in the context of user-defined
ones, but they aren't necessarily the same procedure as the one you
call.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/22/2009 10:24:01 AM

grocery_stocker wrote:
> On May 21, 11:32 am, jameskuyper <jameskuy...@verizon.net> wrote:
....
>> Not really. You've confused the issue by using the same name for all
>> three cases. Let me distinguish them as follows:
>>
>>     char *pc = "123456";
>>     char imp_length[] = "123456";
>>     char exp_length[7] = "123456";
>>
>> Any use of the string literal "123456" anywhere in your program causes
>> at least one unnamed array of char to be created, initialized with the
>> valued '1', '2', '3', '4', '5', '6', '\0', in that order. It's
>> entirely up to the implementation whether or not all uses of "123456"
>> refer to the same array, or whether each such use refers to a
>> different array. In addition, it's entirely up to the implementation
>> whether or not the array created for "123456" occupies the same
>> location in memory as the last seven elements of the array created for
>> "0123456". The behavior of any program that attempts to write anything
>> into one of those blocks of memory is undefined.
>>
>> The variable named pc is a pointer that is initialized to point at the
>> first character in one of those blocks of memory. It could, at any
>> later time, be re-set to point at some other piece of memory. The
>> following statement:
>>
>>     pc = &imp_length[3] ;
>>
>> causes pc to point at the char within imp_length which has the value
>> '4'. Here's where the difference between a data type and a data format
>> comes into play: &imp_length[n] is itself a pointer to the first
>> character of a string with a length of 5-n, for any value of n from 0
>> to 5. All of those strings share the same terminating null character.
>> five of them share the same '5' character, etc. Until you understand
>> that statement, you really don't understand what C strings are.
>>
> 
> I don't see how &imp_len(n) have the same terminating null character
> and how all 5 of them share the same '5 character.

That should have been 6-n, not 5-n, 6 instead of 5, and '6', instead of 
'5'. An early draft of my message had "12345" instead of "123456". When 
I corrected it, I thought I had made all corresponding adjustments, but 
I missed those.

The array imp_length contains the following elements:

	{'1', '2', '3', '4', '5', '6', '\0'}

In C, "A string is a contiguous sequence of characters terminated by and 
including the first null character." (7.1.1p1). Notice the complete lack 
of any requirements on where those characters are located.

&imp_length[6] points at the '\0' character. That is a contiguous 
sequence of 1 character, which ends with a null character; in itself it 
qualifies as a string of length 0.

&imp_length[5] points at the '6' character, which is the start of a 
contiguous sequence of 2 characters, ending with a null character, so 
they constitute a string of length 1; the null character that terminates 
this string is the same as the one that was the entire string of length 
0 pointed at by &imp_length[6].

&imp_length[4] points at the '5' character, which is the start of a 
contiguous sequence of 3 characters, terminated by a null character, so 
they constitute a string of length 2. The '6' character in this string 
is the same as the one in the string of length 1 mentioned above.

All of these overlapping strings are equally usable as such, as far as 
the C standard library is concerned. Note that strings are entirely an 
issue for the C standard library (that's why they're not defined until 
section 7, which describes the library). The C language itself has 
string literals, but strings mean nothing at the language level.

You can pass &imp_length[n], for n from 0 to 6, to any C standard 
library function that handles strings, and that function will treat the 
corresponding portion of imp_length as a string in itself.

>> imp_length is an array of 7 characters; the length is determined
>> implicily by counting the characters in the string literal "123456",
>> and adding 1 for the terminating null character. That array is filled
>> in by copying from the array used store the string literal. In this
>> case, there's no way for your program to even determine whether the
>> string literal's array actually exists; which means that in some cases
>> it won't actually exist; the only copy of those characters could be in
>> imp_length itself. Having been initialized with "123456", you're free
>> to change the contents of that array; in particular, the statement
>>
>>      imp_length[3] = '\0';
>>
>> means that it no longer contains a string of length 6. It now starts
>> with a string of length 3; and contains another string of length 2
>> starting at &imp_length[4]. It also contains 5 other strings, but
>> they're just subsets of those two strings.
>>
> 
> I also don't see how this contains another string of length two
> starting at &imp_length[4].

I hope that's clear now; it's the same string that was pointed by 
&imp_length[4] before the assignment statement. Setting imp_length[3] to 
'\0' changed the length of all the overlapping strings pointed by 
&imp_length[n] for n from 0 to 3, but didn't have any affect on the 
other three overlapping strings contained in imp_length.

0
Reply jameskuyper (5157) 5/22/2009 11:50:10 AM

BartC wrote:
> 
> "jameskuyper" <jameskuyper@verizon.net> wrote in message 
> news:d9fe8456-9e58-4df0-931b-6036c80689b6@g37g2000yqn.googlegroups.com...
....
>>     char word[] = "hello";
>>     char pa = word;
>>     strcpy(pa, "world", sizeof "world");
>>     pa = "other";
> 
> It makes a bit more sense like this:
> 
>     char word[] = "hello";
>     char *pa = word;

Aagh! A single missing character can make a lot of difference. :-(

>     memcpy(pa, "world", sizeof "world");

I should have used strncpy(pa, "world", sizeof word).

>     pa = "other";
> 
> Or perhaps with the copy line like this:
> 
>     strcpy(pa, "world");
> 
> But either way it would go wrong if the "world" string was longer than 
> the "hello" string.

That's why I should have used strncpy(..., sizeof word).
0
Reply jameskuyper (5157) 5/22/2009 11:58:45 AM

On 21 May, 18:57, Jon Harrop <j...@ffconsultancy.com> wrote:
> nick_keighley_nos...@hotmail.com wrote:

> >> I started from Fortran string(i:j)=3Dvalue
>
> [snip huge Scheme program]

10 lines is huge?

> In OCaml, this is just:
>
> =A0 String.blit

How does it know which string to embed (I'm guessing the target
is called "String") and how does it know where to put it?

This seems like the bare minimum of interface
   (string-embed "abcd" "AB" 1)


--
Nick Keighley


0
Reply nick_keighley_nospam (4574) 5/22/2009 12:02:41 PM

On Thu, 21 May 2009, Ben Bacarisse wrote:
> LC's No-Spam Newsreading account writes:

>> Is all this correct ?
>
> Not as bad as it seems from my comments.

Thanks to you (and everybody) for the interesting comments. Some of them 
may look learned tetrapiloctomy, but it is always good to know. In 
particular it may be good to know how imprecise I can be saying 
something about "comparison of string assignment". That level of 
imprecision can be OK for me or my audience, but I appreciate it would 
be different to be OK by chance, or to be OK but imprecise and being 
aware of the imprecision.

>> So the shortest main program which demonstrates my case (where all
>> items are variables assigned explicitly a value, not just initialized)
>> is

>>     char a[4] ;                  /* must use a maximum size */
>>     strcpy(a,"abcd") ;           /* value assigned later THUS */
>
> BANG!  This copies 5 bytes from the literal string to a.  You have
> space for 4.  I'd have written:
>
>      char a[] = "abcd";

I stand corrected.

I'm aware of the terminating null when I pass a Fortran string to a C 
jacket routine ( CALL CROUTINE(STRING//CHAR(0)) ), but tend to forget 
about it the few times I have to write something in C.

But I tend to forget also the terminating semicolon :-)  Both in C and 
Java ... but javac tells me more explicitly "you have forgotten a 
semicolon" w.r.t. cc :-)

Anyhow I'll rewrite my example as

     int i,j ;
     char a[5] ;                  /* must use a maximum size PLUS ONE */
     char *b ;                    /* no size implied */
     strcpy(a,"abcd") ;           /* value assigned later THUS */
     b = "AB" ;                   /* value assigned later THUS */
     printf("a = %s\n", a);
     i=1 ; j=2 ;
     strncpy(a+i,b,j+1-i    ) ;   /* or memcpy */
     printf("a = %s\n", a);

I did not want to illustrate *in particular* strcpy *as such*, but I 
wanted to illustrate "giving a value" to a and b after the 
initialization (is "giving a value" any better than "assigning" ?) ... 
and find the "shortest or more legible equivalent" of

     [ INTEGER I,J ]           !  (optional with the I-N naming rule)
     CHARACTER A*5,B*2         !  (must give a size for both)
     A="abcd"                  !  #1
     B="AB"                    !  #2
     I=1
     J=2
     A(I:J)=B                  !  #3
     WRITE(*,*)'A = ',A

in particular #3 (for me "assignment of a substring") is clearly 
emulated by strncpy. #1 and #2 (for me "assignment of a string") are 
emulated one by a strcpy and one by a pointer assignment, and HAVE to be 
so because of the different way a and b are declared.

-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/22/2009 12:14:08 PM

On Fri, 22 May 2009, robin wrote:
> "glen herrmannsfeldt" wrote:
>
>> Does  a="123456"  in Fortran "copy" a string?
>
> It's an ordinary character assignment.

Maybe it is not by chance that your post is #42 in my news folder.
According to the Hitch Hikers Guide to the Galaxy *the* answer is 42 :-)

I wanted just to say the same. And adding, it is not different from a=b 
where a and b are both declared as character*6.

Just for curiosity, I used the compiler to generate assembly code for 
two simple programs (doing only a="123456" and a=b plus necessary 
declarations). Not something I usually do, and I do not know assembly 
code ... but the two look rather similar.

the first assignment (to a constant) generates

         push      $STRLITPACK_0                                 #2.7
         push      $main$s_$A                                    #2.7
         call      memmove                                       #2.7

while the second (a=b) generates

         push      $main$s_$B                                    #2.7
         push      $main$s_$A                                    #2.7
         call      memmove                                       #2.7

They look remarkably similar (STRLITPACK looks something initalized 
later on to a sequence of .byte	49 .byte 50 .byte 51 .byte 52 .byte 53 
..byte 54 .byte 0)



-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/22/2009 12:29:28 PM

robin wrote:
> "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:gv4dm3$2o6$1@naig.caltech.edu...
> 
>> Does  a="123456"  in Fortran "copy" a string?
> 
> It's an ordinary character assignment.
> 
> 

Fwiw: It is not hard to look at the assembler code produced by gcc or 
gfortran in the two cases. I really don't see much difference. In both 
cases, it seems that a temporary sting is stored and then copied by a 
function call.

Heres's the fortran version test1.f

       character*8 a
       a="Hi There"
       end

gfortran -S test1.f produces

	.file	"test1.f"
	.section .rdata,"dr"
	.align 4
_options.0.533:
	.long	68
	.long	127
	.long	0
	.long	0
	.long	0
	.long	1
	.long	0
LC0:
	.ascii "Hi There"
	.text
..globl _MAIN__
	.def	_MAIN__;	.scl	2;	.type	32;	.endef
_MAIN__:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	subl	$8, %esp
	pushl	$_options.0.533
	pushl	$7
	call	__gfortran_set_options
	addl	$16, %esp
	subl	$4, %esp
	pushl	$8
	pushl	$LC0
	leal	-8(%ebp), %eax
	pushl	%eax
	call	_memmove
	addl	$16, %esp
	leave
	ret
	.def	__gfortran_set_options;	.scl	2;	.type	32;	.endef
	.def	_memmove;	.scl	2;	.type	32;	.endef


and here's the C version test2.c

#include <stdio.h>
#include <string.h>

int main()
{
char a[9];
strcpy(a,"hi there");
return 0;
}


gcc -S test2.c produces


	.file	"test2.c"
	.def	___main;	.scl	2;	.type	32;	.endef
	.section .rdata,"dr"
LC0:
	.ascii "hi there\0"
	.text
..globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	leal	4(%esp), %ecx
	andl	$-16, %esp
	pushl	-4(%ecx)
	pushl	%ebp
	movl	%esp, %ebp
	pushl	%ecx
	subl	$20, %esp
	call	___main
	subl	$4, %esp
	pushl	$9
	pushl	$LC0
	leal	-13(%ebp), %eax
	pushl	%eax
	call	_memcpy
	addl	$16, %esp
	movl	$0, %eax
	movl	-4(%ebp), %ecx
	leave
	leal	-4(%ecx), %esp
	ret
	.def	_memcpy;	.scl	2;	.type	32;	.endef
0
Reply user17588 (148) 5/22/2009 12:32:59 PM

nmm1@cam.ac.uk writes:
> In article <lnmy969hw1.fsf@nuthaus.mib.org>,
> Keith Thompson  <kst-u@mib.org> wrote:
>>glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>>> In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
>>[...]
>>> < Right, but in C there's always the danger of confusing arrays and
>>> < pointers.  A parameter declared to be of an array type is really a
>>> < pointer, and applying sizeof to it will just give you the size of the
>>> < pointer.
>>>
>>> Hopefully new C programmers learn this pretty fast, but yes.
>>[...]
>>
>>In an ideal world they learn it pretty fast.  Unfortunately ...
>>
>>Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>, does a good
>>job of clearing up the confusion.
>
> Don't bet on it.  You do know that it isn't actually specified by
> the C standard, don't you?  I am not denigrating that FAQ, so much
> as pointing out the term "clearing up the confusion" is misleading!
>
> Firstly, the conversion rules between arrays and pointers and back
> again allow for indefinite and infinite implicit recursion - the
> consensus is that this is a constraint on the implementation to
> ensure that they are equivalent, but it's not even hinted at in any
> wording.  It isn't visible in C as such, but becomes so as soon as
> you extend it (e.g. by adding safe pointers, garbage collection,
> OpenMP-style parallelism etc.)
>
> Secondly, the wording of 6.3.2.1#3 is seriously ambiguous about
> WHEN the conversion takes place, and there are certain reasonable
> interpretations that provide visible differences.  During the early
> years of C89 implementations, several of them varied in how they
> implemented array arguments.  This was one of the many ignored NB
> comments on either C89 or C99.  Please ask for examples, if you want.
>
>
> Glen can be excused for thinking that the array/pointer mess is not
> much worse than the Fortran assumed size and array element to array
> one, because you need to have been deeply into the C standard to
> know just how bad it is in ISO C.  K&R C was much cleaner.

Yoiks!  I'm a bit embarrassed to admit that I didn't know any of this,
and looking at the standard I still don't see it.

I've set followups to comp.lang.c.  Feel free to override that if you
have something Fortranish to say.

Here's C99 6.3.2.1p3:

    Except when it is the operand of the sizeof operator or the unary
    & operator, or is a string literal used to initialize an array, an
    expression that has type ``array of type'' is converted to an
    expression with type ``pointer to type'' that points to the
    initial element of the array object and is not an lvalue. If the
    array object has register storage class, the behavior is
    undefined.

That seems relatively straightforward to me (it's the consequences
that make newbies pull their hair out).  An expression of array type
is converted implicitly to a pointer in most contexts.  There are no
conversions of a pointer back to an array (dereferencing is not
conversion).

So what am I missing (and what have the rest of us been missing all
these years)?  Can you provide concrete examples of your first and
second points?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 5/22/2009 4:32:03 PM

In article <lnr5yh6qv0.fsf@nuthaus.mib.org>,
Keith Thompson  <kst-u@mib.org> wrote:
>
>Yoiks!  I'm a bit embarrassed to admit that I didn't know any of this,
>and looking at the standard I still don't see it.
>
>I've set followups to comp.lang.c.  Feel free to override that if you
>have something Fortranish to say.

I gave up on that some time ago, so I won't see the thread.

>Here's C99 6.3.2.1p3:
>
>    Except when it is the operand of the sizeof operator or the unary
>    & operator, or is a string literal used to initialize an array, an
>    expression that has type ``array of type'' is converted to an
>    expression with type ``pointer to type'' that points to the
>    initial element of the array object and is not an lvalue. If the
>    array object has register storage class, the behavior is
>    undefined.
>
>That seems relatively straightforward to me (it's the consequences
>that make newbies pull their hair out).  An expression of array type
>is converted implicitly to a pointer in most contexts.  There are no
>conversions of a pointer back to an array (dereferencing is not
>conversion).

Take a deeper look.  The description of subscription is in terms of
arrays, which derives from the concepts in 6.3.2.1 Lvalues etc.
A pointer (value) is not an lvalue, and the corresponding lvalue is
the array to which it points (or, more usually), the first element
of that array).  I forget the construction now where I could create
an infinite loop of syntax rules - as I said, it's not visible in
plain C.

>So what am I missing (and what have the rest of us been missing all
>these years)?  Can you provide concrete examples of your first and
>second points?

The point is WHEN the conversion is done, and that is most unclear.
It is clear that array syntax is allowed, and has extra syntactic
and semantic properties ('const' and restrict', added in C99).

Consider the following program fragment:

typedef int weeble[5];

void function (weeble arg) {
    weeble *ptr = &arg;
    printf("%ld %ld\n",(long)sizeof(weeble),(long)sizeof(arg));
}

Where is it stated that the conversion is done AFTER parsing and
BEFORE type matching?

To add chaos to the ambiguity, parsing, type matching and the
'evaluation' of sizeof are ALL done in the last sentence of
translation phase 7.  There is nothing in the standard that
distinguishes them in that respect.

In the early days of C89, different vendors interpreted the above
code in all of the three obvious ways (and probably some unobvious
ones, but I never saw them).  The conversion could perfectly well
occur after type matching, which would make the declaration of ptr
valid, or even just before evaluation, which would turn sizeof(arg)
into 5*sizeof(int), as anyone accustomed to saner languages would
expect.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/22/2009 5:05:08 PM

nmm1@cam.ac.uk writes:
> In article <lnr5yh6qv0.fsf@nuthaus.mib.org>,
> Keith Thompson  <kst-u@mib.org> wrote:
>>
>>Yoiks!  I'm a bit embarrassed to admit that I didn't know any of this,
>>and looking at the standard I still don't see it.
>>
>>I've set followups to comp.lang.c.  Feel free to override that if you
>>have something Fortranish to say.
>
> I gave up on that some time ago, so I won't see the thread.

I'm Cc'ing this response to you by e-mail.

>>Here's C99 6.3.2.1p3:
>>
>>    Except when it is the operand of the sizeof operator or the unary
>>    & operator, or is a string literal used to initialize an array, an
>>    expression that has type ``array of type'' is converted to an
>>    expression with type ``pointer to type'' that points to the
>>    initial element of the array object and is not an lvalue. If the
>>    array object has register storage class, the behavior is
>>    undefined.
>>
>>That seems relatively straightforward to me (it's the consequences
>>that make newbies pull their hair out).  An expression of array type
>>is converted implicitly to a pointer in most contexts.  There are no
>>conversions of a pointer back to an array (dereferencing is not
>>conversion).
>
> Take a deeper look.  The description of subscription is in terms of
> arrays, which derives from the concepts in 6.3.2.1 Lvalues etc.
> A pointer (value) is not an lvalue, and the corresponding lvalue is
> the array to which it points (or, more usually), the first element
> of that array).  I forget the construction now where I could create
> an infinite loop of syntax rules - as I said, it's not visible in
> plain C.

Subscripting is defined in terms of unary "*" and "+".  E1[E2] means
(*((E1)+(E2))).  Pointer addition is defined in terms of an array; it
works only if the pointer operand (of type foo*) points to an element
of an array of foo.

I still don't see how this can create an "infinite loop of syntax
rules".  The requirement for pointer addition to refer to an array is
a semantic rule, not a syntax rule.
  
>>So what am I missing (and what have the rest of us been missing all
>>these years)?  Can you provide concrete examples of your first and
>>second points?
>
> The point is WHEN the conversion is done, and that is most unclear.
> It is clear that array syntax is allowed, and has extra syntactic
> and semantic properties ('const' and restrict', added in C99).
>
> Consider the following program fragment:
>
> typedef int weeble[5];
>
> void function (weeble arg) {
>     weeble *ptr = &arg;
>     printf("%ld %ld\n",(long)sizeof(weeble),(long)sizeof(arg));
> }
>
> Where is it stated that the conversion is done AFTER parsing and
> BEFORE type matching?

The above violates a constraint.  The typedef doesn't introduce a new
type, just a synonym for an existing type (C99 6.7.7p3).  So the
declaration
    void function (weeble arg)
is equivalent to
    void function (int *arg)
(C99 6.7.5.3p7).

Thus &arg is of type int**, and ptr is of type weeble*, or int (*)[5].

The only possible hole in this is the question of whether the the use
of the typedef name in the parameter declaration avoids the adjustment
specified in 6.7.5.3p7.  But I don't think it can be reasonably argued
that it does; if it did, we could use a typedef to create a parameter
of array type, something that otherwise doesn't exist.

But the initialization isn't necessary for the following line.
sizeof(weeble) is 5*sizeof(int), and sizeof(arg) is sizeof(int(*)[5]).

As long as you assume that the standard is consistent, I don't see any
ambiguity.

> To add chaos to the ambiguity, parsing, type matching and the
> 'evaluation' of sizeof are ALL done in the last sentence of
> translation phase 7.  There is nothing in the standard that
> distinguishes them in that respect.
>
> In the early days of C89, different vendors interpreted the above
> code in all of the three obvious ways (and probably some unobvious
> ones, but I never saw them).  The conversion could perfectly well
> occur after type matching, which would make the declaration of ptr
> valid, or even just before evaluation, which would turn sizeof(arg)
> into 5*sizeof(int), as anyone accustomed to saner languages would
> expect.

What about the equivalent without a typedef?

void fucntion (int arg[5]) {
    int (*ptr)[5];
    printf("%ld %ld\n", (long)sizeof(int[5]), (long)sizeof(arg));
}

Do you see any ambiguity there?

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply kst-u (21469) 5/22/2009 7:22:51 PM

On May 22, 9:02=A0am, nick_keighley_nos...@hotmail.com wrote:
> On 21 May, 18:57, Jon Harrop <j...@ffconsultancy.com> wrote:
>
> > nick_keighley_nos...@hotmail.com wrote:
> > >> I started from Fortran string(i:j)=3Dvalue
>
> > [snip huge Scheme program]
>
> 10 lines is huge?
>
> > In OCaml, this is just:
> > =A0 String.blit

In Scheme, it's just blit too.  After you implement it, that is.

common complaint against standard Scheme by people coming from
"batteries-included" implementations...
0
Reply namekuseijin (629) 5/22/2009 8:20:06 PM

nmm1@cam.ac.uk wrote:
> 
> The point is WHEN the conversion is done, and that is most unclear.
> It is clear that array syntax is allowed, and has extra syntactic
> and semantic properties ('const' and restrict', added in C99).

You're conflating the conversion of arrays and pointers (6.3.2.1p3) with
the adjustment of function parameter declarations (6.7.5.3p7).
-- 
Larry Jones

It's not denial.  I'm just very selective about the reality I accept.
-- Calvin
0
Reply lawrence.jones2 (565) 5/22/2009 8:28:57 PM

namekuseijin wrote:
> On May 22, 9:02 am, nick_keighley_nos...@hotmail.com wrote:
>> On 21 May, 18:57, Jon Harrop <j...@ffconsultancy.com> wrote:
>> > In OCaml, this is just:
>> > String.blit
> 
> In Scheme, it's just blit too.  After you implement it, that is.
> 
> common complaint against standard Scheme by people coming from
> "batteries-included" implementations...

OCaml's stdlib is hardly batteries included! Indeed, that is why there is a
separate batteries included project... ;-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
0
Reply jon (3267) 5/22/2009 10:52:28 PM

On May 22, 7:52=A0pm, Jon Harrop <j...@ffconsultancy.com> wrote:
> namekuseijin wrote:
> > On May 22, 9:02=A0am, nick_keighley_nos...@hotmail.com wrote:
> >> On 21 May, 18:57, Jon Harrop <j...@ffconsultancy.com> wrote:
> >> > In OCaml, this is just:
> >> > String.blit
>
> > In Scheme, it's just blit too. =A0After you implement it, that is.
>
> > common complaint against standard Scheme by people coming from
> > "batteries-included" implementations...
>
> OCaml's stdlib is hardly batteries included! Indeed, that is why there is=
 a
> separate batteries included project... ;-)

any lang's stdlib is pretty batteries-included next to Scheme's one,
sadly. :P
0
Reply namekuseijin (629) 5/23/2009 3:04:47 AM

nmm1@cam.ac.uk writes:
> In article <lnmy969hw1.fsf@nuthaus.mib.org>,
> Keith Thompson  <kst-u@mib.org> wrote:
>>glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
>>> In comp.lang.fortran Keith Thompson <kst-u@mib.org> wrote:
>>[...]
>>> < Right, but in C there's always the danger of confusing arrays and
>>> < pointers.  A parameter declared to be of an array type is really a
>>> < pointer, and applying sizeof to it will just give you the size of the
>>> < pointer.
>>>
>>> Hopefully new C programmers learn this pretty fast, but yes.
>>[...]
>>
>>In an ideal world they learn it pretty fast.  Unfortunately ...
>>
>>Section 6 of the comp.lang.c FAQ, <http://www.c-faq.com>, does a good
>>job of clearing up the confusion.
>
> Don't bet on it.  You do know that it isn't actually specified by
> the C standard, don't you?  I am not denigrating that FAQ, so much
> as pointing out the term "clearing up the confusion" is misleading!
>
> Firstly, the conversion rules between arrays and pointers and back
> again allow for indefinite and infinite implicit recursion 

I'm gonna need a C&V for that. I am aware of rules of replacing
what appears to be one of the above as if it were one of the 
other, but nothing in the reverse direction, and certainly no
way of getting infinite recursion.

Phil
-- 
Marijuana is indeed a dangerous drug.  
It causes governments to wage war against their own people.
-- Dave Seaman (sci.math, 19 Mar 2009)
0
Reply thefatphil_demunged (1558) 5/23/2009 9:32:56 AM

On 22 May, 23:52, Jon Harrop <j...@ffconsultancy.com> wrote:
> namekuseijin wrote:
> > On May 22, 9:02=A0am, nick_keighley_nos...@hotmail.com wrote:
> >> On 21 May, 18:57, Jon Harrop <j...@ffconsultancy.com> wrote:
> >> > In OCaml, this is just:
> >> > String.blit
>
> > In Scheme, it's just blit too. =A0After you implement it, that is.
>
> > common complaint against standard Scheme by people coming from
> > "batteries-included" implementations...
>
> OCaml's stdlib is hardly batteries included! Indeed, that is why there is=
 a
> separate batteries included project... ;-)

do SRFIs count?

(string-copy! "abcd"  "AB" 1)
0
Reply nick_keighley_nospam (4574) 5/23/2009 1:28:39 PM

<nick_keighley_nospam@hotmail.com> wrote:
> On 19 May, 17:41, LC's No-Spam Newsreading account
> <nos...@mi.iasf.cnr.it> wrote:
>> I am trying to collect equivalent statements in various languages.

>> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
>> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
>> has to use n=j-i+1 (length("AB")).
>>
>> I want an assignment which returns string="aABd"

Javascript always returns a new string; i.e. it doesn't modify in-
place. So you could write:

 str = "abcd";
 val = "AB";
 str = str.substr(0,1) + val + str.substr(3);
 // or
 str = str.substring(0,1) + val + str.substring(3);

The difference between methods is not apparent here but the first
argument of each is the zero-based index, while the second is the
length for substr and is the second index (up to but not including)
for substring. The second argument can be omitted if all characters
to the end of the string are wanted.


0
Reply not172 (91) 5/23/2009 9:42:18 PM

"Ant" <not@home.today> writes:

> <nick_keighley_nospam@hotmail.com> wrote:
>> On 19 May, 17:41, LC's No-Spam Newsreading account
>> <nos...@mi.iasf.cnr.it> wrote:
>>> I am trying to collect equivalent statements in various languages.
>
>>> Let us assume that string="abcd", value="AB", i=2, j=3 (I won't
>>> scandalize if in your favourite language it is i=1 j=2 :=). Nor if one
>>> has to use n=j-i+1 (length("AB")).
>>>
>>> I want an assignment which returns string="aABd"
>
> Javascript always returns a new string; i.e. it doesn't modify in-
> place. So you could write:
>
>  str = "abcd";
>  val = "AB";
>  str = str.substr(0,1) + val + str.substr(3);
>  // or
>  str = str.substring(0,1) + val + str.substring(3);
>
> The difference between methods is not apparent here but the first
> argument of each is the zero-based index, while the second is the
> length for substr and is the second index (up to but not including)
> for substring. The second argument can be omitted if all characters
> to the end of the string are wanted.

Yes, but this is not what is asked.

If javascript strings are immutable, when it's asked to have mutable
strings, then you must implement a mutable string abstraction, however
you want.

One solution would be to implement mutable strings as arrays of
characters (of java strings containing each one character).  The
advantage would be that the mapping from index to character would be 
easier.  The downside would be that it would take more space.

Another solution would be to implement mutable strings as cords, or as
overlayed javascript strings.

It's bound to require a lot more code.

-- 
__Pascal Bourguignon__
0
Reply pjb (7645) 5/23/2009 9:54:39 PM

nick_keighley_nospam@hotmail.com wrote:
> do SRFIs count?

Yes!

> (string-copy! "abcd"  "AB" 1)

Much better. :-)

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
0
Reply jon (3267) 5/23/2009 11:39:33 PM

>> Javascript always returns a new string; i.e. it doesn't modify in-
>> place. So you could write:

>>  str = str.substr(0,1) + val + str.substr(3);
>>  str = str.substring(0,1) + val + str.substring(3);

I wrote (for Fortran string(i:j)=value) in Java
string=string.substring(0,i)+value+string.substring(j+1) ;

substr or substring should be equivalent if one inserts between
locations i and j

> Yes, but this is not what is asked.

the above was the closest match to "seemingly" altering string in place
(the fact it is a new copy does not matter to me insofar it has the same 
name)

> If javascript strings are immutable, when it's asked to have mutable
> strings,

a nice alternative seems to be

StringBuffer sb = new StringBuffer(string) ;
sb.replace(i,j+1,value) ;

-- 
----------------------------------------------------------------------
nospam@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.
0
Reply nospam110 (153) 5/25/2009 9:23:52 AM

LC's No-Spam Newsreading account wrote:
>>> Javascript always returns a new string; i.e. it doesn't modify in-
>>> place. So you could write:
>
>>>  str = str.substr(0,1) + val + str.substr(3);
>>>  str = str.substring(0,1) + val + str.substring(3);
>
> I wrote (for Fortran string(i:j)=value) in Java
> string=string.substring(0,i)+value+string.substring(j+1) ;
>
> substr or substring should be equivalent if one inserts between
> locations i and j
>
>> Yes, but this is not what is asked.
>
> the above was the closest match to "seemingly" altering string in
> place (the fact it is a new copy does not matter to me insofar it has
> the same name)

OK, now imagine a string with 100 million characters and you're updating a 
million short substrings in it.

You will be replacing the entire 100MB string a million times.

C's approach would naturally update the string in-place, which is also the 
most efficient.

>> If javascript strings are immutable, when it's asked to have mutable
>> strings,


(Why do people who invent languages keep coming up with these silly rules, 
just (apparently) to make life difficult?)

-- 
Bart 

0
Reply bartc (783) 5/25/2009 12:03:33 PM

"BartC" <bartc@freeuk.com> writes:

> LC's No-Spam Newsreading account wrote:
>>>> Javascript always returns a new string; i.e. it doesn't modify in-
>>>> place. So you could write:
>>
>>>>  str = str.substr(0,1) + val + str.substr(3);
>>>>  str = str.substring(0,1) + val + str.substring(3);
>>
>> I wrote (for Fortran string(i:j)=value) in Java
>> string=string.substring(0,i)+value+string.substring(j+1) ;
>>
>> substr or substring should be equivalent if one inserts between
>> locations i and j
>>
>>> Yes, but this is not what is asked.
>>
>> the above was the closest match to "seemingly" altering string in
>> place (the fact it is a new copy does not matter to me insofar it has
>> the same name)
>
> OK, now imagine a string with 100 million characters and you're
> updating a million short substrings in it.
>
> You will be replacing the entire 100MB string a million times.
>
> C's approach would naturally update the string in-place, which is also
> the most efficient.
>
>>> If javascript strings are immutable, when it's asked to have mutable
>>> strings,
>
>
> (Why do people who invent languages keep coming up with these silly
> rules, just (apparently) to make life difficult?)


Ah but immutable data structures have a lot of advantages.

So far, it was mainly in the debugging that was avoided: once you've
created the data, it couldn't change, so you couldn't introduce any
bug in changing it.  

It simplifies the dependencies between the various parts of the
program, since only one part, the one who created the data, could
write it, and the other parts could only read it.

This fact means that once you have multi-threaded processing using
multi-core processors, that is real parallelism, it allows to avoid
even more bugs and you may therefore benefit more easily of
performance increase expected from multi-core processors.

Modern languages will more and more have immutable data structures,
keeping in mind the trend toward multi-core (see for example Clojure).

(These same considerations also favor purely functional programming
languages, or at least, languages leaning toward purely functional.
See also Clojure)


Anyways, even in a procedural programming language, you may benefit
from immutable data structures: just implement the immutable abstract
data types you want.

-- 
__Pascal Bourguignon__
0
Reply pjb (7645) 5/25/2009 1:39:03 PM

"Pascal J. Bourguignon" <pjb@informatimago.com> wrote in message
news:7c4ov9b8ug.fsf@pbourguignon.anevia.com...
> "BartC" <bartc@freeuk.com> writes:

>>>> If javascript strings are immutable, when it's asked to have mutable
>>>> strings,

>> (Why do people who invent languages keep coming up with these silly
>> rules, just (apparently) to make life difficult?)
>
>
> Ah but immutable data structures have a lot of advantages.

> So far, it was mainly in the debugging that was avoided: once you've
> created the data, it couldn't change, so you couldn't introduce any
> bug in changing it.
>
> It simplifies the dependencies between the various parts of the
> program, since only one part, the one who created the data, could
> write it, and the other parts could only read it.

That's more to do with read/write access, or possibly visibility, something
a little different.

I think immutability would mean even the creator of the data can't modify
it.

> This fact means that once you have multi-threaded processing using
> multi-core processors, that is real parallelism, it allows to avoid
> even more bugs and you may therefore benefit more easily of
> performance increase expected from multi-core processors.

I'd prefer that that was someone else's headache so that I can carry on
programming in the way I want.

So that when I create an instance of a compound (not array) type, such as a
string, record, set, or even a range, I expect to be able to modify part of
it without having to replace the whole thing, assuming the 'whole thing' can
be written to at all. (Arrays and lists I guess are generally mutable?)

I understand this may introduce problems with sharing, but as I say the
implementer needs to worry about that not the user of the language.
(Ideally; I suppose in practice the programmer has to cooperate to some
extent when dealing with parallelism and such.)

> Modern languages will more and more have immutable data structures,
> keeping in mind the trend toward multi-core (see for example Clojure).

I normally use my own languages so I can do what I like. It just means a
nightmare if I ever have to translate code to something more mainstream..
and modern. Although my main problem is likely to be the lack of 'go to',
since that seems to be out of fashion.

-- 
Bart

0
Reply bartc (783) 5/25/2009 2:41:06 PM

"BartC" <bartc@freeuk.com> writes:

> "Pascal J. Bourguignon" <pjb@informatimago.com> wrote in message
> news:7c4ov9b8ug.fsf@pbourguignon.anevia.com...
>> "BartC" <bartc@freeuk.com> writes:
>
>>>>> If javascript strings are immutable, when it's asked to have mutable
>>>>> strings,
>
>>> (Why do people who invent languages keep coming up with these silly
>>> rules, just (apparently) to make life difficult?)
>>
>>
>> Ah but immutable data structures have a lot of advantages.
>
>> So far, it was mainly in the debugging that was avoided: once you've
>> created the data, it couldn't change, so you couldn't introduce any
>> bug in changing it.
>>
>> It simplifies the dependencies between the various parts of the
>> program, since only one part, the one who created the data, could
>> write it, and the other parts could only read it.
>
> That's more to do with read/write access, or possibly visibility, something
> a little different.
>
> I think immutability would mean even the creator of the data can't modify
> it.
>
>> This fact means that once you have multi-threaded processing using
>> multi-core processors, that is real parallelism, it allows to avoid
>> even more bugs and you may therefore benefit more easily of
>> performance increase expected from multi-core processors.
>
> I'd prefer that that was someone else's headache so that I can carry on
> programming in the way I want.
>
> So that when I create an instance of a compound (not array) type, such as a
> string, record, set, or even a range, I expect to be able to modify part of
> it without having to replace the whole thing, assuming the 'whole thing' can
> be written to at all. (Arrays and lists I guess are generally mutable?)
>
> I understand this may introduce problems with sharing, but as I say the
> implementer needs to worry about that not the user of the language.
> (Ideally; I suppose in practice the programmer has to cooperate to some
> extent when dealing with parallelism and such.)

Yes, I forgot to mention also the fact that immutable data means you
can share it, so you usually spare memory (and therefore processor
cycles).

But of course, it depends on the kind of algorithms you work with, and
sometimes it's more efficient to use mutable data structures (at
least, internally, inside a function or a module).


Notably, with OO, since an object is defined as the encapsulation of
data (state) and code (methods), if you only had immutable objects it
wouldn't be too meaningful: an immutable object has no state, since it
cannot change.


>> Modern languages will more and more have immutable data structures,
>> keeping in mind the trend toward multi-core (see for example Clojure).
>
> I normally use my own languages so I can do what I like. It just means a
> nightmare if I ever have to translate code to something more mainstream..
> and modern. Although my main problem is likely to be the lack of 'go to',
> since that seems to be out of fashion.

In conclusion, it's indeed better to have a language allowing to use
both paradigms, or all paradigms, (such as Common Lisp), including the
meta-programming paradigms, so you can define your own language.

We agree.

-- 
__Pascal Bourguignon__
0
Reply pjb (7645) 5/25/2009 3:06:43 PM

In article <7cr5yd9q7w.fsf@pbourguignon.anevia.com>,
Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>
>In conclusion, it's indeed better to have a language allowing to use
>both paradigms, or all paradigms, (such as Common Lisp), including the
>meta-programming paradigms, so you can define your own language.

Really?  It makes program analysis and validation almost impossible,
which is a real nightmare for people who prefer programs to be
correct.

For reasons I don't fully understand, the LISP (and Lisp) community
have always been self-disciplined enough to (usually) avoid blowing
their own feet off.  But there is no doubt that the flexibility of
that language means that it is impossible to write a validator for
an arbitrary program.

Similar remarks apply to parallelising compilers, of course, which
is why Fortran still leads in that area.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/25/2009 3:19:26 PM

nmm1@cam.ac.uk writes:

> In article <7cr5yd9q7w.fsf@pbourguignon.anevia.com>,
> Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>>
>>In conclusion, it's indeed better to have a language allowing to use
>>both paradigms, or all paradigms, (such as Common Lisp), including the
>>meta-programming paradigms, so you can define your own language.
>
> Really?  It makes program analysis and validation almost impossible,
> which is a real nightmare for people who prefer programs to be
> correct.
>
> For reasons I don't fully understand, the LISP (and Lisp) community
> have always been self-disciplined enough to (usually) avoid blowing
> their own feet off.  But there is no doubt that the flexibility of
> that language means that it is impossible to write a validator for
> an arbitrary program.

1- we never write arbitrary programs.

2- even in stricter programming language, it's always possible to
   implement an interpreter pattern, and then you won't have proved
   anything about the code interpreted by your program.

That said, and knowing the theorical limitations of such tools,   I
agree that it would be nice if global analysis and verification tools
were more common (and not just type checking compilers at the
compilation-unit level).


> Similar remarks apply to parallelising compilers, of course, which
> is why Fortran still leads in that area.

And also the fact that until Fortran dies if it ever occurs, this will
always be the programming language in which compiler writer will be
the most experimented, and therefore which they'll be able to optimize
the best.   Lisp only comes close second. ;-)


-- 
__Pascal Bourguignon__
0
Reply pjb (7645) 5/25/2009 3:46:28 PM

In article <7ceiud9odn.fsf@pbourguignon.anevia.com>,
Pascal J. Bourguignon <pjb@informatimago.com> wrote:
>
>1- we never write arbitrary programs.

A very good principle!

>2- even in stricter programming language, it's always possible to
>   implement an interpreter pattern, and then you won't have proved
>   anything about the code interpreted by your program.

That is true, but a common characteristic of the interpreters for
which Fortran is used as the implementation strategy is simplicity.
And that always helps with validation :-)

>That said, and knowing the theorical limitations of such tools,   I
>agree that it would be nice if global analysis and verification tools
>were more common (and not just type checking compilers at the
>compilation-unit level).

Indeed.

>And also the fact that until Fortran dies if it ever occurs, this will
>always be the programming language in which compiler writer will be
>the most experimented, and therefore which they'll be able to optimize
>the best.   Lisp only comes close second. ;-)

Actually, no.  C and C++ overtook Fortran quite a while back.  You
might well ask why so much effort has resulted in so little progress
in those languages, compared to Fortran, ....


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/25/2009 4:08:14 PM

Hello,

On 2009-05-25 11:46:28 -0400, pjb@informatimago.com (Pascal J. 
Bourguignon) said:

> And also the fact that until Fortran dies if it ever occurs, this will
> always be the programming language in which compiler writer will be
> the most experimented, and therefore which they'll be able to optimize
> the best.

Fortran's anti-aliasing rules help more,
for both parallel processing and optimization,
than the age or experience of the compiler writers.

-- 
Cheers!

Dan Nagle

0
Reply dannagle (1019) 5/25/2009 4:42:42 PM

nmm1@cam.ac.uk wrote:
> C and C++ overtook Fortran quite a while back.

In what sense?

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
0
Reply jon (3267) 5/25/2009 11:21:33 PM

In article <fI-dncxx5YgWu4bXnZ2dnUVZ8oKdnZ2d@brightview.co.uk>,
Jon Harrop  <jon@ffconsultancy.com> wrote:
>nmm1@cam.ac.uk wrote:
>> C and C++ overtook Fortran quite a while back.
>
>In what sense?

In the sense of the previous paragraph, to which I was responding,
but which you have snipped.


Regards,
Nick Maclaren.
0
Reply nmm12 (898) 5/26/2009 8:29:37 AM

nmm1@cam.ac.uk wrote:
> In article <fI-dncxx5YgWu4bXnZ2dnUVZ8oKdnZ2d@brightview.co.uk>,
> Jon Harrop  <jon@ffconsultancy.com> wrote:
>>nmm1@cam.ac.uk wrote:
>>> C and C++ overtook Fortran quite a while back.
>>
>>In what sense?
> 
> In the sense of the previous paragraph, to which I was responding,
> but which you have snipped.

Can you justify your belief?

-- 
Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/?u
0
Reply jon (3267) 5/26/2009 12:17:23 PM

73 Replies
81 Views

(page loaded in 0.603 seconds)

Similiar Articles:


















7/17/2012 7:32:34 AM


Reply: