comp.lang.ada
 help / color / mirror / Atom feed
* Ada Idioms Progress Preview
@ 2001-08-03  4:16 James Rogers
  2001-08-03 19:45 ` Robert Dewar
  0 siblings, 1 reply; 41+ messages in thread
From: James Rogers @ 2001-08-03  4:16 UTC (permalink / raw)


I have posted a VERY early version of the Ada idioms page at
http://home.att.net/~jimmaureenrogers/index.html

I have started at a beginner level. I will progress to more advanced
idioms.

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-03  4:16 Ada Idioms Progress Preview James Rogers
@ 2001-08-03 19:45 ` Robert Dewar
  2001-08-03 22:02   ` James Rogers
  2001-08-06 22:33   ` Stanley R. Allen
  0 siblings, 2 replies; 41+ messages in thread
From: Robert Dewar @ 2001-08-03 19:45 UTC (permalink / raw)


James Rogers <jimmaureenrogers@worldnet.att.net> wrote in message news:<3B6A2616.C89C9760@worldnet.att.net>...
> I have posted a VERY early version of the Ada idioms page at
> http://home.att.net/~jimmaureenrogers/index.html
> 
> I have started at a beginner level. I will progress to more advanced
> idioms.
> 
> Jim Rogers
> Colorado Springs, Colorado USA



To me this is not a list of idioms, but rather a tutorial of Ada
features. That may have its own merits, but a list of real idioms
would be separately useful.

If there is a feature X in Ada that does Y, then saying that X is
an idiom for Y is not very helpful. To me an idiom is a combination
of features that is not so obvious, e.g. the following for labeling
branches of cases

   when XYZ => XYZ_Case : declare
      declarations
   begin
      ...
   end XYZ_Case;

or the use of declare blocks to get local suppression

   declare
      pragma Suppress (...)
   begin
      ...
   end;

or the use of pragma Import to suppress initialization when an address
clause is present.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-03 19:45 ` Robert Dewar
@ 2001-08-03 22:02   ` James Rogers
  2001-08-06 22:33   ` Stanley R. Allen
  1 sibling, 0 replies; 41+ messages in thread
From: James Rogers @ 2001-08-03 22:02 UTC (permalink / raw)


Robert Dewar wrote:
> 
> To me this is not a list of idioms, but rather a tutorial of Ada
> features. That may have its own merits, but a list of real idioms
> would be separately useful.
> 
> If there is a feature X in Ada that does Y, then saying that X is
> an idiom for Y is not very helpful. To me an idiom is a combination
> of features that is not so obvious, e.g. the following for labeling
> branches of cases

I have been struggling with just this issue. 

To a person learning Ada, but familiar with other languages, the
things you call a "feature" will appear to be an idiom. 

Having looked up the word "idiom" in "The American Heritage
Dictionary", I get the following definitions:

1. A speech form or expression of a given language that is peculiar
to itself grammatically or that cannot be understood from the
individual meanings of its elements.
2. The specific grammatical, syntactic, and structural character of
a given language.
3. A regional speech or dialect.
4. A specialized vocabulary used by a group of people; jargon.
5. A style of artistic expression characteristic of a given
individual, school, period, or medium.

Clearly none of these are exactly what I am looking for. The word
is used somewhat differently in a programming language context.
I do see that the word idiom can be used both generally, and for
specialized groups. It appears that you understand an idiom to be
more specialized than definition 2 above.

I have been working through a way to present both the general and the
specialized idioms for Ada. I have started with the general idioms.
I do want to include more specialized idioms such as those mentioned
by Robert Dewar and Ehud Lamm. The big challenge is to organize the
document so that readers can find the idioms in which they are
interested.

Please keep suggesting idioms. I am sure that I have not personally
used all Ada idioms. 

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-03 19:45 ` Robert Dewar
  2001-08-03 22:02   ` James Rogers
@ 2001-08-06 22:33   ` Stanley R. Allen
  2001-08-07  2:45     ` tmoran
  1 sibling, 1 reply; 41+ messages in thread
From: Stanley R. Allen @ 2001-08-06 22:33 UTC (permalink / raw)


Robert Dewar wrote:
> To me an idiom is a combination
> of features that is not so obvious, e.g. the following for labeling
> branches of cases
> 
>    when XYZ => XYZ_Case : declare
>       declarations
>    begin
>       ...
>    end XYZ_Case;
> 
> or the use of declare blocks to get local suppression
> 
>    declare
>       pragma Suppress (...)
>    begin
>       ...
>    end;
> 
> or the use of pragma Import to suppress initialization when an address
> clause is present.

Or making an array null or full based on a boolean configuration:

   Feature_Present : constant Boolean := False;  -- change to true
   Size_Of_Array : constant := 100_000;
   The_Array : The_Array_Type (1 .. Boolean'Pos (Feature_Present) * Size_Of_Array);
      -- null array if feature is not present

--
Stanley Allen
mailto:Stanley_R_Allen-NR@Raytheon.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-06 22:33   ` Stanley R. Allen
@ 2001-08-07  2:45     ` tmoran
  2001-08-07 12:15       ` Larry Kilgallen
  2001-08-08  2:19       ` Robert Dewar
  0 siblings, 2 replies; 41+ messages in thread
From: tmoran @ 2001-08-07  2:45 UTC (permalink / raw)


Perhaps Ada should not have idioms.  An idiom makes no sense to someone
who doesn't know it, eg "He lost his marbles".  Unless it's so well
known that you can guarantee that a maintenance programmer will
recognize it, you shouldn't be, and shouldn't have to be, using it.
What's really wanted, I think, is a set of "here's how you use
Ada features to accomplish this purpose" techniques.  The declare
block, for instance, is clear to someone seeing it for the first
time, but doesn't spring to mind for a new Ada programmer wondering
how to locally suppress checking, or how to save a string of
unknown length.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-07  2:45     ` tmoran
@ 2001-08-07 12:15       ` Larry Kilgallen
  2001-08-07 13:26         ` Philip Anderson
  2001-08-08  2:23         ` Robert Dewar
  2001-08-08  2:19       ` Robert Dewar
  1 sibling, 2 replies; 41+ messages in thread
From: Larry Kilgallen @ 2001-08-07 12:15 UTC (permalink / raw)


In article <SCIb7.37009$Kd7.22894159@news1.rdc1.sfba.home.com>, tmoran@acm.org writes:
> Perhaps Ada should not have idioms.  An idiom makes no sense to someone
> who doesn't know it, eg "He lost his marbles".  Unless it's so well
> known that you can guarantee that a maintenance programmer will
> recognize it, you shouldn't be, and shouldn't have to be, using it.

	MY_VAR : MY_TYPE := MY_FUNC(37);

is an idiom.  It is strange to someone just learning Ada, but familiar
to somewhat who knows Ada.  That is analogous to idioms in English.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-07 12:15       ` Larry Kilgallen
@ 2001-08-07 13:26         ` Philip Anderson
  2001-08-08  2:23         ` Robert Dewar
  1 sibling, 0 replies; 41+ messages in thread
From: Philip Anderson @ 2001-08-07 13:26 UTC (permalink / raw)


Larry Kilgallen wrote:
> 
> In article <SCIb7.37009$Kd7.22894159@news1.rdc1.sfba.home.com>, tmoran@acm.org writes:
> > Perhaps Ada should not have idioms.  An idiom makes no sense to someone
> > who doesn't know it, eg "He lost his marbles".  Unless it's so well
> > known that you can guarantee that a maintenance programmer will
> > recognize it, you shouldn't be, and shouldn't have to be, using it.
> 
>         MY_VAR : MY_TYPE := MY_FUNC(37);
> 
> is an idiom.  It is strange to someone just learning Ada, but familiar
> to somewhat who knows Ada.  That is analogous to idioms in English.

No, that's just syntax, analogous to English syntax.

Idiom: "an expression characteristic of a particular language not
logically or grammatically explicable".

Natural language idioms can be baffling for near-fluent learners as well
as beginners, while being perfectly familiar to native speakers.  And
American idioms sometimes confuse the British and vice versa.


That's not what we want for Ada, which was tmoran's point.  But
propagating easily-understood  example code is "a different kettle of
fish", in line with Ada's goal of being easier to read than to write. 
If there are a number of ways of achieving something, the easiest to
read is probably the best, but that may not come out of trial and error.

      My_String : string := Get_Line;

to read a string of unkown length is an idiom.


-- 
hwyl/cheers,
Philip Anderson
Alenia Marconi Systems
Cwmbr�n, Cymru/Wales



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-07  2:45     ` tmoran
  2001-08-07 12:15       ` Larry Kilgallen
@ 2001-08-08  2:19       ` Robert Dewar
  2001-08-08 15:13         ` Ted Dennison
  2001-08-10 21:02         ` Jay Nabonne
  1 sibling, 2 replies; 41+ messages in thread
From: Robert Dewar @ 2001-08-08  2:19 UTC (permalink / raw)


tmoran@acm.org wrote in message news:<SCIb7.37009$Kd7.22894159@news1.rdc1.sfba.home.com>...
> Perhaps Ada should not have idioms. 

I understand Tom's point here, and I would rephrase it as a requirement
that Ada idiom's be obvious once seen to someone who knows Ada. That's
true for example of Stanley's Boolean'Pos idiom (which is indeed a
useful one to know). 

So when you read one of these idioms, the reaction should be one of

a) ah, yes, I know that, and immediately know what it means

b) ah, interesting way of doing things, yes, I understand it and
will remember this in future.

It should not be:

c) Gadzooks! What on earth does that mean, let me reach for the LRM.
Ah, yes, finally figured it out -- to clever for me!



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-07 12:15       ` Larry Kilgallen
  2001-08-07 13:26         ` Philip Anderson
@ 2001-08-08  2:23         ` Robert Dewar
  2001-08-08  5:58           ` Ehud Lamm
  1 sibling, 1 reply; 41+ messages in thread
From: Robert Dewar @ 2001-08-08  2:23 UTC (permalink / raw)


Kilgallen@eisner.decus.org.nospam (Larry Kilgallen) wrote in message news:<4V+as+yNIsOy@eisner.encompasserve.org>...
 
> 	MY_VAR : MY_TYPE := MY_FUNC(37);
> 
> is an idiom.  It is strange to someone just learning Ada, but 
> familiar to somewhat who knows Ada.  That is analogous to idioms in 
> English.

And I think that example is *EXACTLY* wrong. This is a straightforward
construct in the Ada language, and is by no stretch of the imagination
an idiom. The analogy with someone just learning english is false. 
Someone just learning English might have trouble understanding:

   the cat sat on the mat

but that does not make it an idiom!

And I think that the proposed catalog of idioms will be far more
useful if it is not simply a rehash of basic Ada rules (as the above
example would be).

In a sense, the example above is simply an instantiation of an axiom,
where the axiom is:

   object_declaration ::=
        defining_identifier_list : [aliased] [constant] 
                                    subtype_indication
                                   [:= expression];

An idiom is more like a theorem, whose meaning must be deduced by
combining axioms, where I am using axiom to mean a basic rule of the
language.

Now if you want to talk about Ada constructs that might be unfamiliar
to someone whose primary knowledge is some other language X, then
that's indeed also useful, but is the solution to a different problem



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-08  2:23         ` Robert Dewar
@ 2001-08-08  5:58           ` Ehud Lamm
  0 siblings, 0 replies; 41+ messages in thread
From: Ehud Lamm @ 2001-08-08  5:58 UTC (permalink / raw)


The way I see it, idioms indeed are the things Robert described as
>To me an idiom is a combination of features that is not so obvious

but I extend the defintion a bit.
Even if we are talking about a specific feature, and not a combination of
features, I'd be willing to call something an idiom, if it is not obvious.
Which brings us the question of what 'obvious' really is...

Since most programmers have backgrounds in other languages, some Ada
features may not be very obvious at first. In fact, I'd assume these are
features that accomplish something that requires an idiom in some other
language.
So an idiom list may include end-results that may encourage idiomatic
programming in other languages, but can be achieved in Ada using one of
Ada's "special" features.

Ehud Lamm







^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-08  2:19       ` Robert Dewar
@ 2001-08-08 15:13         ` Ted Dennison
  2001-08-08 18:03           ` tmoran
  2001-08-09 20:36           ` Florian Weimer
  2001-08-10 21:02         ` Jay Nabonne
  1 sibling, 2 replies; 41+ messages in thread
From: Ted Dennison @ 2001-08-08 15:13 UTC (permalink / raw)


In article <5ee5b646.0108071819.6e84e33d@posting.google.com>, Robert Dewar
says...
>
>I understand Tom's point here, and I would rephrase it as a requirement
>that Ada idiom's be obvious once seen to someone who knows Ada. That's
>true for example of Stanley's Boolean'Pos idiom (which is indeed a
>useful one to know). 
..
>It should not be:
>
>c) Gadzooks! What on earth does that mean, let me reach for the LRM.
>Ah, yes, finally figured it out -- to clever for me!

Out of curiosity, which category would you place the "Rosen Trick" in? I'd think
the latter. It might be farily clear to an Ada expert what the code does, but
without extensive commenting (or knowledge of the trick) it would be rather
tough to figure out why someone would go through all that trouble.

For those who don't know: The Rosen Trick, if I remember correctly, involves
using self-referencing access fields in a record structure to allow modifiction
of an "in" parameter. By convention, it should only be considered when the
client's view of the parameter won't change, but some internal bookeeping needs
to be done. Do a groups.google search for more info.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-08 15:13         ` Ted Dennison
@ 2001-08-08 18:03           ` tmoran
  2001-08-09 20:36           ` Florian Weimer
  1 sibling, 0 replies; 41+ messages in thread
From: tmoran @ 2001-08-08 18:03 UTC (permalink / raw)


>Out of curiosity, which category would you place the "Rosen Trick" in?
  If it's obscure, it's an idiom.  If it's common and clear, but not
so obvious that everyone invents it for himself, perhaps it should be
called a "cliche".  Both are useful, and both should be written up,
but they should be in separate chapters.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-08 15:13         ` Ted Dennison
  2001-08-08 18:03           ` tmoran
@ 2001-08-09 20:36           ` Florian Weimer
  1 sibling, 0 replies; 41+ messages in thread
From: Florian Weimer @ 2001-08-09 20:36 UTC (permalink / raw)


Ted Dennison<dennison@telepath.com> writes:

>>c) Gadzooks! What on earth does that mean, let me reach for the LRM.
>>Ah, yes, finally figured it out -- to clever for me!
>
> Out of curiosity, which category would you place the "Rosen Trick" in? 

(b), I think.  It's necessary to implement memoizing transparently,
and useful in other ways, too.

> It might be farily clear to an Ada expert what the code does, but
> without extensive commenting (or knowledge of the trick) it would be
> rather tough to figure out why someone would go through all that
> trouble.

The trick per se is not very hard to grok, I think.  In my opionen,
it's surprising that this construction is necessary, and that it is
indeed valid Ada.  To figure out the last two things, you need
probably some expertise, but this is not necessary to understand the
idiom and use it.

After all, do you know the origins of all the English idioms you're
using? ;-)



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-08  2:19       ` Robert Dewar
  2001-08-08 15:13         ` Ted Dennison
@ 2001-08-10 21:02         ` Jay Nabonne
  2001-08-10 21:51           ` Larry Kilgallen
  2001-08-13 14:05           ` Ted Dennison
  1 sibling, 2 replies; 41+ messages in thread
From: Jay Nabonne @ 2001-08-10 21:02 UTC (permalink / raw)


"Robert Dewar" <dewar@gnat.com> wrote in message
news:5ee5b646.0108071819.6e84e33d@posting.google.com...
> tmoran@acm.org wrote in message
news:<SCIb7.37009$Kd7.22894159@news1.rdc1.sfba.home.com>...
> > Perhaps Ada should not have idioms.
>
> I understand Tom's point here, and I would rephrase it as a requirement
> that Ada idiom's be obvious once seen to someone who knows Ada. That's
> true for example of Stanley's Boolean'Pos idiom (which is indeed a
> useful one to know).
>
> So when you read one of these idioms, the reaction should be one of
>
> a) ah, yes, I know that, and immediately know what it means
>
> b) ah, interesting way of doing things, yes, I understand it and
> will remember this in future.
>
> It should not be:
>
> c) Gadzooks! What on earth does that mean, let me reach for the LRM.
> Ah, yes, finally figured it out -- to clever for me!
>

(This isn't really a response to Robert, but my news reader lost the top of
this thread, and this was the highest root I could attach a message to. :)

As a C/C++ programmer who is looking with interest at Ada (after a rather
entertaining discussion about Code Red in comp.lang.c++), what would be most
useful for me - and it's what I thought of when I saw the word idiom - is
something that says "in order to do <blah>, given that there's more than one
way to do it within the Ada language, here's how you write code that looks
like an Ada programmer wrote it and doesn't look like a
C++-programmer-writing-Ada wrote it.".

I'm interested in how to "think in Ada"...

Jay-





^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-10 21:02         ` Jay Nabonne
@ 2001-08-10 21:51           ` Larry Kilgallen
  2001-08-13 14:19             ` Ted Dennison
  2001-08-13 14:05           ` Ted Dennison
  1 sibling, 1 reply; 41+ messages in thread
From: Larry Kilgallen @ 2001-08-10 21:51 UTC (permalink / raw)


In article <3_Xc7.45$NM5.84779@news.pacbell.net>, "Jay Nabonne" <jay@rightagain.com> writes:

> As a C/C++ programmer who is looking with interest at Ada (after a rather
> entertaining discussion about Code Red in comp.lang.c++), what would be most
> useful for me - and it's what I thought of when I saw the word idiom - is
> something that says "in order to do <blah>, given that there's more than one
> way to do it within the Ada language, here's how you write code that looks
> like an Ada programmer wrote it and doesn't look like a
> C++-programmer-writing-Ada wrote it.".
> 
> I'm interested in how to "think in Ada"...

The criterion for success is that someone reading your code cannot tell
whether your background is C or Fortran.  (Or anything else, but the
original statement, so far as I can tell, is "It is possible to write
Fortran in any language".)

WWW.AdaPower.com should have an item on "Ada for C programmers" that
gives some ideas of the ways "not" to do it.  Perhaps one technique
for those whose background is Csomething is to think very hard in
an Ada program before taking the address of something.  Generally
it is not necessary, but there is a tendency to do it if C is on
your mind.  Another trick might be not to assume you can guess what
the machine code is going to look like.  Passing a record as a
parameter is _not_ less efficient than passing a pointer, since
what Ada does under the covers is typically a pointer.

Of course things that don't involve instruction-level efficiencies
are no different -- if you read every block on the disk it will still
take a while, so higher level program efficiency rules still count.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-10 21:02         ` Jay Nabonne
  2001-08-10 21:51           ` Larry Kilgallen
@ 2001-08-13 14:05           ` Ted Dennison
  2001-08-13 14:19             ` Marin David Condic
                               ` (2 more replies)
  1 sibling, 3 replies; 41+ messages in thread
From: Ted Dennison @ 2001-08-13 14:05 UTC (permalink / raw)


In article <3_Xc7.45$NM5.84779@news.pacbell.net>, Jay Nabonne says...
>
>useful for me - and it's what I thought of when I saw the word idiom - is
>something that says "in order to do <blah>, given that there's more than one
>way to do it within the Ada language, here's how you write code that looks
>like an Ada programmer wrote it and doesn't look like a
>C++-programmer-writing-Ada wrote it.".
>
>I'm interested in how to "think in Ada"...

The best advice I can give you today is to go to the Ada Source Code Treasury at
http://www.adapower.com/adacode.html . The master site itself is useful too.

Based on my experience with native C speakers, here are some basic things to get
you started:

o  Strings in Ada are *very* different from Strings in C. Ada strings end at the
end of the array (or slice of it you specify), not at some arbitrarily-chosen
"terminator" character. Look into the "&" operator for arrays, and the array
attributes 'length, 'first, and 'last. 'image is damn nice too. Don't be
discouraged if you have trouble with this seemingly simple thing. Conceptually,
this is probably the biggest difference the languages have.

o  The techniques you learn for dealing with strings can be used for *all*
arrays.

o  Make yourself familiar with the language defined attributes (
http://www.ada-auth.org/~acats/arm-html/RM-K.html ).

o  Passing a large data structure as a parameter does *not* mean that the whole
thing gets copied. The compiler will internally pass a reference to the
structure if that would be more efficient. Do *not* use pointers yourself to
force this effect.

o  You almost never need pointers.

o  If you think you need a pointer, see the previous point. :-)

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-10 21:51           ` Larry Kilgallen
@ 2001-08-13 14:19             ` Ted Dennison
  0 siblings, 0 replies; 41+ messages in thread
From: Ted Dennison @ 2001-08-13 14:19 UTC (permalink / raw)


In article <jc8NR9ynpNEv@eisner.encompasserve.org>, Larry Kilgallen says...
>
>whether your background is C or Fortran.  (Or anything else, but the
>original statement, so far as I can tell, is "It is possible to write
>Fortran in any language".)

The way it was stated in "Real Programmers Don't Use Pascal" (DATAMATION, July
1983) was: "...the determined Real Programmer can write Fortran programs in any
language." That at the end of a paragraph describing Ada, no less. :-)

(online reference:
http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?Real+Programmers+Don%27t+Use+Pascal
)

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 14:05           ` Ted Dennison
@ 2001-08-13 14:19             ` Marin David Condic
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
  2001-08-14  1:39             ` Slicing ( Ada Idioms Progress Preview ) Warren W. Gay VE3WWG
  2 siblings, 0 replies; 41+ messages in thread
From: Marin David Condic @ 2001-08-13 14:19 UTC (permalink / raw)


I'd have to agree. Maybe we ought to have something in the AdaPower FAQ on
this. My experience has indicated that the most frequently messed up things
by C/C++ programmers using Ada are:

1) Improper handling of strings because of dissimilar language models &
trying to force Ada strings to look like C strings.

2) Improper passing of parameters because of C's historic lack of
pass-by-reference & all the history that goes with this.

3) Pointers to every blankety-blank thing on the whole blankety-blank planet
because in C/C++ you have to do it this way.

4) Improper use of 'Address - usually related to some version of #3 above.

But, then again, I still think the three most frequently sung songs are
"Happy Birthday To You", "Auld Lang Syne" and "Inna Godda Davida" :-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ted Dennison" <dennison@telepath.com> wrote in message
news:E8Rd7.282$D4.307@www.newsranger.com...
> In article <3_Xc7.45$NM5.84779@news.pacbell.net>, Jay Nabonne says...
> >
> >useful for me - and it's what I thought of when I saw the word idiom - is
> >something that says "in order to do <blah>, given that there's more than
one
> >way to do it within the Ada language, here's how you write code that
looks
> >like an Ada programmer wrote it and doesn't look like a
> >C++-programmer-writing-Ada wrote it.".
> >
> >I'm interested in how to "think in Ada"...
>
> The best advice I can give you today is to go to the Ada Source Code
Treasury at
> http://www.adapower.com/adacode.html . The master site itself is useful
too.
>
> Based on my experience with native C speakers, here are some basic things
to get
> you started:
>
> o  Strings in Ada are *very* different from Strings in C. Ada strings end
at the
> end of the array (or slice of it you specify), not at some
arbitrarily-chosen
> "terminator" character. Look into the "&" operator for arrays, and the
array
> attributes 'length, 'first, and 'last. 'image is damn nice too. Don't be
> discouraged if you have trouble with this seemingly simple thing.
Conceptually,
> this is probably the biggest difference the languages have.
>
> o  The techniques you learn for dealing with strings can be used for *all*
> arrays.
>
> o  Make yourself familiar with the language defined attributes (
> http://www.ada-auth.org/~acats/arm-html/RM-K.html ).
>
> o  Passing a large data structure as a parameter does *not* mean that the
whole
> thing gets copied. The compiler will internally pass a reference to the
> structure if that would be more efficient. Do *not* use pointers yourself
to
> force this effect.
>
> o  You almost never need pointers.
>
> o  If you think you need a pointer, see the previous point. :-)
>
> ---
> T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
>           home email - mailto:dennison@telepath.com





^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 14:05           ` Ted Dennison
  2001-08-13 14:19             ` Marin David Condic
@ 2001-08-13 15:47             ` Ole-Hjalmar Kristensen
  2001-08-13 16:22               ` Marin David Condic
                                 ` (4 more replies)
  2001-08-14  1:39             ` Slicing ( Ada Idioms Progress Preview ) Warren W. Gay VE3WWG
  2 siblings, 5 replies; 41+ messages in thread
From: Ole-Hjalmar Kristensen @ 2001-08-13 15:47 UTC (permalink / raw)


Ted Dennison<dennison@telepath.com> writes:

> In article <3_Xc7.45$NM5.84779@news.pacbell.net>, Jay Nabonne says...
> >
> >useful for me - and it's what I thought of when I saw the word idiom - is
> >something that says "in order to do <blah>, given that there's more than one
> >way to do it within the Ada language, here's how you write code that looks
> >like an Ada programmer wrote it and doesn't look like a
> >C++-programmer-writing-Ada wrote it.".
> >
> >I'm interested in how to "think in Ada"...
> 
> The best advice I can give you today is to go to the Ada Source Code Treasury at
> http://www.adapower.com/adacode.html . The master site itself is useful too.
> 
> Based on my experience with native C speakers, here are some basic things to get
> you started:
> 
> o  Strings in Ada are *very* different from Strings in C. Ada strings end at the
> end of the array (or slice of it you specify), not at some arbitrarily-chosen
> "terminator" character. Look into the "&" operator for arrays, and the array
> attributes 'length, 'first, and 'last. 'image is damn nice too. Don't be
> discouraged if you have trouble with this seemingly simple thing. Conceptually,
> this is probably the biggest difference the languages have.

One thing which can be said in favour of having a terminator character
is that it frees you from having to store the length explicitly. The
length of a string is usually different from the size of the array
used to store the string.
So, in a sense a C string is more self-describing than a plain Ada
string. 
Of course, as soon as you call a procedure, you can use a slice, but
you still need the actual length to decide which slice.

On the balance, I would rather have Ada strings.

> 
> o  The techniques you learn for dealing with strings can be used for *all*
> arrays.
> 
> o  Make yourself familiar with the language defined attributes (
> http://www.ada-auth.org/~acats/arm-html/RM-K.html ).
> 
> o  Passing a large data structure as a parameter does *not* mean that the whole
> thing gets copied. The compiler will internally pass a reference to the
> structure if that would be more efficient. Do *not* use pointers yourself to
> force this effect.
> 
> o  You almost never need pointers.
> 
> o  If you think you need a pointer, see the previous point. :-)
> 
> ---
> T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
>           home email - mailto:dennison@telepath.com

-- 
Kabelsalat ist gesund.

Ole-Hj. Kristensen



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
@ 2001-08-13 16:22               ` Marin David Condic
  2001-08-13 18:48               ` Larry Kilgallen
                                 ` (3 subsequent siblings)
  4 siblings, 0 replies; 41+ messages in thread
From: Marin David Condic @ 2001-08-13 16:22 UTC (permalink / raw)


I look at it as a case of "You can pay me now or pay me later". The static
array business is true of both languages since both allocate a fixed size
array to hold a string of some indeterminate length <= the size of the
array. In C the "convention" is to stick a null immediately after the last
valid character, but nothing especially enforces this. I used to rely on the
last-non-blank character in Ada83 to determine where the end of the valid
string was (Then use slices, etc, for manipulation.) In either case, you
have to search the string for the character whenever you need to know where
it ends - thus making it pay to keep that info around.

So building a custom fixed-max-length string in Ada is pretty trivial. There
you calculate the last valid character at assignment and keep that info
around for all subsequent operations. I'd done that as well - saving the
processing time at the expense of having to work with a non-language defined
construct with some inconvenience. (Not too much, but some.) You paid once
up front to find the length, then that was that. You could do the same in
C/C++ with a struct or a class - albeit with less checking - but its
probably about a wash as to which would require more effort.

Nowadays with Ada95 and Ada.Strings.Bounded and Ada.Strings.Unbounded, its a
whole different ballgame. I usually recommend just using
Ada.Strings.Unbounded because most of the time its easier and the penalty is
unimportant in most apps. I'd even recommend telling newcomers to start
right there and forget about fixed length strings except for two problems:
You need to understand fixed strings to deal with Ada's syntax & semantics
and you need fixed strings for lots of predefined packages like Text_IO.
(Maybe Ada0x can make it possible to use just Unbounded strings? At least
define parallel packages to Text_IO for them.)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ole-Hjalmar Kristensen" <ohk@clustra.com> wrote in message
news:umqr8ug55d9.fsf@maestro.clustra.com...
>
> One thing which can be said in favour of having a terminator character
> is that it frees you from having to store the length explicitly. The
> length of a string is usually different from the size of the array
> used to store the string.
> So, in a sense a C string is more self-describing than a plain Ada
> string.
> Of course, as soon as you call a procedure, you can use a slice, but
> you still need the actual length to decide which slice.
>
> On the balance, I would rather have Ada strings.
>






^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
  2001-08-13 16:22               ` Marin David Condic
@ 2001-08-13 18:48               ` Larry Kilgallen
  2001-08-14  7:05                 ` Ole-Hjalmar Kristensen
  2001-08-13 20:20               ` James Rogers
                                 ` (2 subsequent siblings)
  4 siblings, 1 reply; 41+ messages in thread
From: Larry Kilgallen @ 2001-08-13 18:48 UTC (permalink / raw)


In article <umqr8ug55d9.fsf@maestro.clustra.com>, Ole-Hjalmar Kristensen <ohk@clustra.com> writes:

> One thing which can be said in favour of having a terminator character
> is that it frees you from having to store the length explicitly. The
> length of a string is usually different from the size of the array
> used to store the string.

That works until the day that all you need to know is the length.
At that point you must walk the string if you are terminator-based.
An example would be a search for all the "long" strings.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
  2001-08-13 16:22               ` Marin David Condic
  2001-08-13 18:48               ` Larry Kilgallen
@ 2001-08-13 20:20               ` James Rogers
  2001-08-14  1:09                 ` Warren W. Gay VE3WWG
  2001-08-16 18:42                 ` Jay Nabonne
  2001-08-13 21:47               ` Ted Dennison
  2001-08-14  8:49               ` Lutz Donnerhacke
  4 siblings, 2 replies; 41+ messages in thread
From: James Rogers @ 2001-08-13 20:20 UTC (permalink / raw)


Ole-Hjalmar Kristensen wrote:
> 
> One thing which can be said in favour of having a terminator character
> is that it frees you from having to store the length explicitly. The
> length of a string is usually different from the size of the array
> used to store the string.
> So, in a sense a C string is more self-describing than a plain Ada
> string.
> Of course, as soon as you call a procedure, you can use a slice, but
> you still need the actual length to decide which slice.
> 
> On the balance, I would rather have Ada strings.

An old saying is "there is no free lunch". In other words, nothing
comes for free. In the case of a C string, you do not explicitly
carry around the length of a string. Instead, you rely on a convention
stating that the logical end of the string is indicated by a null
character.

The C approach presents two very real costs:

1) You must serially read the string to find the terminating null
   character. This operation is very expensive if you only need to
   determine the length of the string.

2) Sometimes the null character is omitted. Since C arrays are
   unbounded, this causes your program to read beyond the end of
   the string until it finds a null character. The resulting
   length will be incorrect. When copying or editing a string
   this problem will result in data corruption and undefined
   behaviors.

Another less common cost occurs when copying C strings. The most
efficient copy operation for C arrays is the memcpy function.
This function allows you to copy blocks of memory efficiently.
If you try to use memcpy to copy strings you will find some
real problems. In those cases you want to copy the actual array
of characters, not just the logical string contained in it.
The problem is that the C sizeof operator does not report the
correct size of arrays outside the immediate scope where they
are declared. Instead you will only get the size of the pointer
to the first element of the array. Therefore, to efficiently
copy C strings using memcpy you must provide a second "length"
argument, which may not be readily available.

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
                                 ` (2 preceding siblings ...)
  2001-08-13 20:20               ` James Rogers
@ 2001-08-13 21:47               ` Ted Dennison
  2001-08-14  7:37                 ` Ole-Hjalmar Kristensen
  2001-08-14 13:22                 ` Marin David Condic
  2001-08-14  8:49               ` Lutz Donnerhacke
  4 siblings, 2 replies; 41+ messages in thread
From: Ted Dennison @ 2001-08-13 21:47 UTC (permalink / raw)


In article <umqr8ug55d9.fsf@maestro.clustra.com>, Ole-Hjalmar Kristensen says...
>One thing which can be said in favour of having a terminator character
>is that it frees you from having to store the length explicitly. The
>length of a string is usually different from the size of the array
>used to store the string.

It frees you from that problem in *some* cases. I find that most of the time I
don't change the string, so I can declare it perfectly sized. When you do that,
you are not storing the length explicitly, but rather implicitly in the array
bounds. As others have mentioned, you also don't have to iterate through every
valid data element to derive this piece of implicit information like you do with
C. Thus perfectly-sized Ada strings give you the best of both worlds.

Unfortunately, the most notable exception to this is in reading data from
Text_IO, which is also one of the first things a newbie will want to do with Ada
strings. :-(

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 20:20               ` James Rogers
@ 2001-08-14  1:09                 ` Warren W. Gay VE3WWG
  2001-08-14  6:15                   ` James Rogers
  2001-08-21  5:54                   ` C strings, was " David Thompson
  2001-08-16 18:42                 ` Jay Nabonne
  1 sibling, 2 replies; 41+ messages in thread
From: Warren W. Gay VE3WWG @ 2001-08-14  1:09 UTC (permalink / raw)


James Rogers wrote:
> Ole-Hjalmar Kristensen wrote:
> > One thing which can be said in favour of having a terminator character
> > is that it frees you from having to store the length explicitly. The
> > length of a string is usually different from the size of the array
> > used to store the string.
> > So, in a sense a C string is more self-describing than a plain Ada
> > string.
> > Of course, as soon as you call a procedure, you can use a slice, but
> > you still need the actual length to decide which slice.
> >
> > On the balance, I would rather have Ada strings.
> 
> An old saying is "there is no free lunch". In other words, nothing
> comes for free. In the case of a C string, you do not explicitly
> carry around the length of a string. Instead, you rely on a convention
> stating that the logical end of the string is indicated by a null
> character.
> 
> The C approach presents two very real costs:
> 
> 1) You must serially read the string to find the terminating null
>    character. This operation is very expensive if you only need to
>    determine the length of the string.

To be honest, it works reasonably well for C/C++ because most strings in
a program tend to be short (of course this varies by application!) It would 
be nice to have someone sample some Open Sourced packages and come 
up with an average length, but I suspect that it would
be short enough. It is true for _some_ C strings/applications, that this 
could be a significant overhead factor.

> 2) Sometimes the null character is omitted. Since C arrays are
>    unbounded, this causes your program to read beyond the end of
>    the string until it finds a null character. The resulting
>    length will be incorrect. 

I'm not really wanting to support C/C++, but we should be careful
about what is being said here.. its really only a problem if you
_need_ a nul byte at the end. There are C programs that work with
fixed sized strings, like Ada, though this tends to be rarer (it
sometimes is done with embedded SQL/C). If you then need to pass
the fixed string to a printf() or other function that expects a
"C string", then yes, this then becomes a problem (just as it does
for Ada supplying a string for C).

> When copying or editing a string
>    this problem will result in data corruption and undefined
>    behaviors.

This is again, not necessarily true, but it does happen if the 
C programmer is not careful. If instead, the user
uses strncpy() for example, where the maximum size of the destination
array is given, then this does not happen. However, if you strncpy()
the maximum # of characters, you don't get a nul byte at the end.
Novice C programmers often miss this subtle point ;-)

One way to avoid this is to use a technique with strncpy() :

#define BUF_LEN 8

void
func(const char *in_str_with_maybe_no_null) {
   char my_buf[BUF_LEN];

   strncpy(my_buf,in_str_with_maybe_no_null,BUF_LEN-1)[BUF_LEN-1] = 0;

This restricts the copy to BUF_LEN-1 characters + 1 guaranteed nul byte.
It works because strncpy() the function, returns the (char *) pointer to
my_buf, resulting in the final assignment:

   my_buf[BUF_LEN-1] = 0;

You can do this in a much less cryptic way, but I have found it useful
in C programs, and it takes up less screen real-estate this way ;-)

> Another less common cost occurs when copying C strings. The most
> efficient copy operation for C arrays is the memcpy function.
> This function allows you to copy blocks of memory efficiently.
> If you try to use memcpy to copy strings you will find some
> real problems. In those cases you want to copy the actual array
> of characters, not just the logical string contained in it.

Have you said this in reverse? Normally you don't want to copy
anything beyond the nul byte, unless you're copying fixed length
arrays of characters, without treating nul as a special marker.

> The problem is that the C sizeof operator does not report the
> correct size of arrays outside the immediate scope where they
> are declared. 

OK, you're saying when you pass arrays into a C function, when
the array is declared external to that function. Something like:

void func2(char *str) {
   // what is the array size of str?
}

void func1() {
   char my_array[31];

   func2(my_array);
}

This is a weakness, but if you know that func2() should work
with fixed length arrays of a certain size, you can use:

void func2(char str[31]) {
   // what is the array size of str?
}

instead. However, I agree that this is feeble, compared to the 
way Ada passes array bounds information.

> Instead you will only get the size of the pointer
> to the first element of the array. 

OK, it sounds like you're suggesting the following:

void my_func(char *str) {
   int slen = sizeof str;    // which does not make sense

But this is nonsense anyway - no self respecting C programmer would
do this, because you are obviously asking for the size of the pointer ;-)

However, if you declared this instead:

void my_func(char str[31]) {
   int array_len = sizeof str;  // this comes close to size of array

(on many platforms : array_len=32 here due to padding)

> Therefore, to efficiently
> copy C strings using memcpy you must provide a second "length"
> argument, which may not be readily available.
> 
> Jim Rogers
> Colorado Springs, Colorado USA

I'm not sure what you're pointing to here, but if you were to 
"efficiently" copy the string, you must have the assurance of 
a nul byte (so you can stop copying when you hit it with strcpy()) or a
specified length (for memcpy()). Or you might need both if you use
strncpy().

But if it is a "C-string", then it does have a nul byte, and is 
efficient to copy (copying stops at the nul byte - memcpy() is not
used to implement strncpy()).

I'm not wanting to defend C, but we want to be correct about the
defects when we launch criticism of C/C++.  Otherwise, Ada programmers
lose respect ;-)
-- 
Warren W. Gay VE3WWG
http://members.home.net/ve3wwg



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Slicing ( Ada Idioms Progress Preview )
  2001-08-13 14:05           ` Ted Dennison
  2001-08-13 14:19             ` Marin David Condic
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
@ 2001-08-14  1:39             ` Warren W. Gay VE3WWG
  2 siblings, 0 replies; 41+ messages in thread
From: Warren W. Gay VE3WWG @ 2001-08-14  1:39 UTC (permalink / raw)


Ted Dennison wrote:
...
> >I'm interested in how to "think in Ada"...
...
> Based on my experience with native C speakers, here are some basic things to get
> you started:
> 
> o  Strings in Ada are *very* different from Strings in C. Ada strings end at the
> end of the array (or slice of it you specify), not at some arbitrarily-chosen
> "terminator" character. Look into the "&" operator for arrays, and the array
> attributes 'length, 'first, and 'last. 'image is damn nice too. Don't be
> discouraged if you have trouble with this seemingly simple thing. Conceptually,
> this is probably the biggest difference the languages have.
> 
> o  The techniques you learn for dealing with strings can be used for *all*
> arrays.
...
> o  You almost never need pointers.
> 
> o  If you think you need a pointer, see the previous point. :-)

I think the other very important aspect of string handling is something Ted
pointed out in another thread: You work with fixed length strings a little
differently than you're used to (ie. Unbounded_Strings are not always necessary).
 
  o  sometimes keeping track of it's true length (when necessary)

     My_String        : String(1..64);  -- of max size
     My_String_Length : Integer;        -- My_String's logical length

  o  declaring the fixed length string with the required size, upon demand:

  procedure whatever is
     Computed_Length : Integer;
  begin
     ...
     Computed_Length := ...;

     declare
       Buffer : String(1..Computed_Length);
     begin
       -- code that uses Buffer...

In the same vein :

  o  Fixed length strings of an exact size can be passed to functions/procedures :

     Procedure_Call(Buffer(1..Computed_Length),...);

THe called procedure gets a string of the exact size :

     procedure Procedure_Call(Buffer : String) is
     begin
        -- Use string of Buffer'Length bytes..

While it was obvious that declare blocks allow you to introduce new variables
mid-way through a procedure, it was not obvious to me that you might want to do
that for the simple reason of getting a precisely sized buffer or string. Once
I caught onto that, I've found that I've rarely wanted to use Bounded or Unbounded
strings.

One last warning important thing about Ada strings, concerns slicing!
I got burnt on this recently (even though I know that I should always
use 'First and 'Last etc... I learned my lesson).

When using a string passed to you, be careful, as in this fragment :

     procedure My_Procedure(Buffer : String) is
       Copied_Str : String(1..Buffer'Length);
     begin
       if Buffer'Length >= 2 then
          Copied_Str(1..2) := Buffer(1..2); -- This is bad!

You look at Buffer, and you think, "but I know String() starts at 1", and so
this slice assignment looks OK. But if the caller does this:

     My_Procedure(Supplied_String(16..20));

then My_Procedure fails, because Buffer'First is 16, and Buffer'Last is 20!

So always be diligent about using 'First and 'Last, and be very careful
about assumptions concerning the array bounds in general.
-- 
Warren W. Gay VE3WWG
http://members.home.net/ve3wwg



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  1:09                 ` Warren W. Gay VE3WWG
@ 2001-08-14  6:15                   ` James Rogers
  2001-08-14 14:03                     ` Warren W. Gay VE3WWG
  2001-08-21  5:54                   ` C strings, was " David Thompson
  1 sibling, 1 reply; 41+ messages in thread
From: James Rogers @ 2001-08-14  6:15 UTC (permalink / raw)


"Warren W. Gay VE3WWG" wrote:
> 
> James Rogers wrote:
> > An old saying is "there is no free lunch". In other words, nothing
> > comes for free. In the case of a C string, you do not explicitly
> > carry around the length of a string. Instead, you rely on a convention
> > stating that the logical end of the string is indicated by a null
> > character.
> >
> > The C approach presents two very real costs:
> >
> > 1) You must serially read the string to find the terminating null
> >    character. This operation is very expensive if you only need to
> >    determine the length of the string.
> 
> To be honest, it works reasonably well for C/C++ because most strings in
> a program tend to be short (of course this varies by application!) It would
> be nice to have someone sample some Open Sourced packages and come
> up with an average length, but I suspect that it would
> be short enough. It is true for _some_ C strings/applications, that this
> could be a significant overhead factor.

I would not like to make a claim about the "average" size of strings
in C applications. I suspect the size varies quite a bit.

> > 2) Sometimes the null character is omitted. Since C arrays are
> >    unbounded, this causes your program to read beyond the end of
> >    the string until it finds a null character. The resulting
> >    length will be incorrect.
> 
> I'm not really wanting to support C/C++, but we should be careful
> about what is being said here.. its really only a problem if you
> _need_ a nul byte at the end. There are C programs that work with
> fixed sized strings, like Ada, though this tends to be rarer (it
> sometimes is done with embedded SQL/C). If you then need to pass
> the fixed string to a printf() or other function that expects a
> "C string", then yes, this then becomes a problem (just as it does
> for Ada supplying a string for C).

The definition of a C string is a null terminated array of characters.
C functions that do not require the null termination do not
actually use strings. They merely use arrays of characters. This may
seem like a subtle point, but it is critical. Functions expecting
a C string for an argument absolutely rely on the existence of the
nul byte at the end of the logical string.

> > When copying or editing a string
> >    this problem will result in data corruption and undefined
> >    behaviors.
> 
> This is again, not necessarily true, but it does happen if the
> C programmer is not careful. If instead, the user
> uses strncpy() for example, where the maximum size of the destination
> array is given, then this does not happen. However, if you strncpy()
> the maximum # of characters, you don't get a nul byte at the end.
> Novice C programmers often miss this subtle point ;-)

Absolutely true. This problem only occurs when the C programmer
omits the terminating nul byte. Unfortunately this omission is easy
to achieve.

> One way to avoid this is to use a technique with strncpy() :
> 
> #define BUF_LEN 8
> 
> void
> func(const char *in_str_with_maybe_no_null) {
>    char my_buf[BUF_LEN];
> 
>    strncpy(my_buf,in_str_with_maybe_no_null,BUF_LEN-1)[BUF_LEN-1] = 0;
> 
> This restricts the copy to BUF_LEN-1 characters + 1 guaranteed nul byte.
> It works because strncpy() the function, returns the (char *) pointer to
> my_buf, resulting in the final assignment:
> 
>    my_buf[BUF_LEN-1] = 0;
> 
> You can do this in a much less cryptic way, but I have found it useful
> in C programs, and it takes up less screen real-estate this way ;-)

And this approach assumes that copying only BUF_LEN characters will
result is valid data. Sometimes it will. Sometimes BUF_LEN may be
too small, resulting in a truncated string.

> 
> > Another less common cost occurs when copying C strings. The most
> > efficient copy operation for C arrays is the memcpy function.
> > This function allows you to copy blocks of memory efficiently.
> > If you try to use memcpy to copy strings you will find some
> > real problems. In those cases you want to copy the actual array
> > of characters, not just the logical string contained in it.
> 
> Have you said this in reverse? Normally you don't want to copy
> anything beyond the nul byte, unless you're copying fixed length
> arrays of characters, without treating nul as a special marker.

No, I am saying that strncpy() is less efficient than memcpy.
It is possible to make an exact copy of a string using memcpy.
In fact the entire character array will be copied, not just the
data up to the null.

> > The problem is that the C sizeof operator does not report the
> > correct size of arrays outside the immediate scope where they
> > are declared.
> 
> OK, you're saying when you pass arrays into a C function, when
> the array is declared external to that function. Something like:
> 
> void func2(char *str) {
>    // what is the array size of str?
> }
> 
> void func1() {
>    char my_array[31];
> 
>    func2(my_array);
> }
> 
> This is a weakness, but if you know that func2() should work
> with fixed length arrays of a certain size, you can use:
> 
> void func2(char str[31]) {
>    // what is the array size of str?
> }
> 
> instead. However, I agree that this is feeble, compared to the
> way Ada passes array bounds information.
> 
> > Instead you will only get the size of the pointer
> > to the first element of the array.
> 
> OK, it sounds like you're suggesting the following:
> 
> void my_func(char *str) {
>    int slen = sizeof str;    // which does not make sense

No, I am suggesting:

void my_func( char str[])
   int slen = sizeof str; // which makes sense within the declaration
                          // scope of the actual parameter.

> However, if you declared this instead:
> 
> void my_func(char str[31]) {
>    int array_len = sizeof str;  // this comes close to size of array
> 
> (on many platforms : array_len=32 here due to padding)

Nope, not what I wanted at all. See, this works because sizeof is used
within the same scope as the declaration of str.

> 
> > Therefore, to efficiently
> > copy C strings using memcpy you must provide a second "length"
> > argument, which may not be readily available.
> >
> > Jim Rogers
> > Colorado Springs, Colorado USA
> 
> I'm not sure what you're pointing to here, but if you were to
> "efficiently" copy the string, you must have the assurance of
> a nul byte (so you can stop copying when you hit it with strcpy()) or a
> specified length (for memcpy()). Or you might need both if you use
> strncpy().

Correct. The point is that C *requires* the nul terminator for a
string but cannot enforce the requirement. Enforcement is left up
to the programmer. C functions cannot determine the size of an
arbitrary length array passed to them without also passing an
additional parameter.

> 
> But if it is a "C-string", then it does have a nul byte, and is
> efficient to copy (copying stops at the nul byte - memcpy() is not
> used to implement strncpy()).
> 
> I'm not wanting to defend C, but we want to be correct about the
> defects when we launch criticism of C/C++.  Otherwise, Ada programmers
> lose respect ;-)

I agree. The problem really revolves around the C attitude that the
programmer must provide all the discipline necessary to produce a
correct program. The language makes no distinction between liberty
and capability. My general rule for C is that almost anything is
allowed, but MANY things are not advised. 

All this aside, I believe I have demonstrated that C strings are not
necessarily more efficient or more self-describing than Ada strings.
This is particularly true when your solutions to the problems I 
pose are to create fixed length C strings, roughly paralleling the
structure of Ada strings. At the same time the C string still needs
the extra nul byte at the end to meet the definition of a string.

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 18:48               ` Larry Kilgallen
@ 2001-08-14  7:05                 ` Ole-Hjalmar Kristensen
  0 siblings, 0 replies; 41+ messages in thread
From: Ole-Hjalmar Kristensen @ 2001-08-14  7:05 UTC (permalink / raw)


Kilgallen@eisner.decus.org.nospam (Larry Kilgallen) writes:

> In article <umqr8ug55d9.fsf@maestro.clustra.com>, Ole-Hjalmar Kristensen <ohk@clustra.com> writes:
> 
> > One thing which can be said in favour of having a terminator character
> > is that it frees you from having to store the length explicitly. The
> > length of a string is usually different from the size of the array
> > used to store the string.
> 
> That works until the day that all you need to know is the length.
> At that point you must walk the string if you are terminator-based.
> An example would be a search for all the "long" strings.

Yes, that's correct. I did not say it's an ideal situation. As Marin
said, it's a tradeoff.
In Ada you don't know the length of the string unless you store it
separately or use Strings.(Un)bounded.
In C, you have to find the length explicitly if you need it.
Of course there is nothing prohibiting you from doing the other thing
in both languages, except that the standard string processing is
geared towards the predominant method in each of the languages.

-- 
Kabelsalat ist gesund.

Ole-Hj. Kristensen



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 21:47               ` Ted Dennison
@ 2001-08-14  7:37                 ` Ole-Hjalmar Kristensen
  2001-08-14 14:59                   ` Ted Dennison
  2001-08-14 13:22                 ` Marin David Condic
  1 sibling, 1 reply; 41+ messages in thread
From: Ole-Hjalmar Kristensen @ 2001-08-14  7:37 UTC (permalink / raw)


Ted Dennison<dennison@telepath.com> writes:

> In article <umqr8ug55d9.fsf@maestro.clustra.com>, Ole-Hjalmar Kristensen says...
> >One thing which can be said in favour of having a terminator character
> >is that it frees you from having to store the length explicitly. The
> >length of a string is usually different from the size of the array
> >used to store the string.
> 
> It frees you from that problem in *some* cases. I find that most of the time I
> don't change the string, so I can declare it perfectly sized. When you do that,
> you are not storing the length explicitly, but rather implicitly in the array
> bounds. As others have mentioned, you also don't have to iterate through every
> valid data element to derive this piece of implicit information like you do with
> C. Thus perfectly-sized Ada strings give you the best of both worlds.
> 

But you usually don't need to know the length of the string, precisely
because it has a sentinel value at the end :-)

Perfectly-sized C string are no problems either:

char x[] = "a perfect string";

I was thinking of the case where you cannot statically allocate a
perfectly sized string, which pops up whenever you have to get
variable sized strings from somewhere, as you describe below.

Btw., I'm not saying that C strings are superior in general or trying
to start a war, just that there are cases when using a sentinel value
makes sense.

> Unfortunately, the most notable exception to this is in reading data from
> Text_IO, which is also one of the first things a newbie will want to do with Ada
> strings. :-(
> 
> ---
> T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
>           home email - mailto:dennison@telepath.com


-- 
Kabelsalat ist gesund.

Ole-Hj. Kristensen



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 15:47             ` Ole-Hjalmar Kristensen
                                 ` (3 preceding siblings ...)
  2001-08-13 21:47               ` Ted Dennison
@ 2001-08-14  8:49               ` Lutz Donnerhacke
  2001-08-14  9:38                 ` Ole-Hjalmar Kristensen
  4 siblings, 1 reply; 41+ messages in thread
From: Lutz Donnerhacke @ 2001-08-14  8:49 UTC (permalink / raw)


* Ole-Hjalmar Kristensen wrote:
>One thing which can be said in favour of having a terminator character is
>that it frees you from having to store the length explicitly.

This requires an out-of-band terminator, which does not exists in C.
Instead they prefer to use a valid character they do not need at the moment.

But the real problem of a terminator character is creating a view:
In order to reference a substring you have to create a full copy of the
substring because you have to insert the terminal character. Inserting it
directly into the main version would cause serve damage.

Dealing with copies:
  - is time inefficient.
  - is semantical different modulo modifications.
  - is space inefficient.
  - requires heap space instead of stack space.

>The length of a string is usually different from the size of the array
>used to store the string.

It's not necessary to provide a buffer to hold any possible string of a
given type if you can pass complex objects to or from a function. C can only
pass primitive types and therefore switched to passing pointers of implicit
terminated arrays.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  8:49               ` Lutz Donnerhacke
@ 2001-08-14  9:38                 ` Ole-Hjalmar Kristensen
  2001-08-14  9:54                   ` Lutz Donnerhacke
  2001-08-14 16:44                   ` Darren New
  0 siblings, 2 replies; 41+ messages in thread
From: Ole-Hjalmar Kristensen @ 2001-08-14  9:38 UTC (permalink / raw)


lutz@iks-jena.de (Lutz Donnerhacke) writes:

> * Ole-Hjalmar Kristensen wrote:
> >One thing which can be said in favour of having a terminator character is
> >that it frees you from having to store the length explicitly.
> 
> This requires an out-of-band terminator, which does not exists in C.
> Instead they prefer to use a valid character they do not need at the moment.
> 
> But the real problem of a terminator character is creating a view:
> In order to reference a substring you have to create a full copy of the
> substring because you have to insert the terminal character. Inserting it
> directly into the main version would cause serve damage.
> 
> Dealing with copies:
>   - is time inefficient.
>   - is semantical different modulo modifications.
>   - is space inefficient.
>   - requires heap space instead of stack space.
> 
> >The length of a string is usually different from the size of the array
> >used to store the string.
> 
> It's not necessary to provide a buffer to hold any possible string of a
> given type if you can pass complex objects to or from a function. C can only
> pass primitive types and therefore switched to passing pointers of implicit
> terminated arrays.

Close, but not quite. C will happily pass records by value.

-- 
Kabelsalat ist gesund.

Ole-Hj. Kristensen



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  9:38                 ` Ole-Hjalmar Kristensen
@ 2001-08-14  9:54                   ` Lutz Donnerhacke
  2001-08-14 14:51                     ` James Rogers
  2001-08-14 16:44                   ` Darren New
  1 sibling, 1 reply; 41+ messages in thread
From: Lutz Donnerhacke @ 2001-08-14  9:54 UTC (permalink / raw)


* Ole-Hjalmar Kristensen wrote:
>lutz@iks-jena.de (Lutz Donnerhacke) writes:
>> It's not necessary to provide a buffer to hold any possible string of a
>> given type if you can pass complex objects to or from a function. C can
>> only pass primitive types and therefore switched to passing pointers of
>> implicit terminated arrays.
>
>Close, but not quite. C will happily pass records by value.

Yep, interesting. Tested with a traditional compiler.

I wonder why C choosed to use inband signaling that heavily.
They could use clear oob signaling for error signaling, array length ...
But they don't. Why? Very strange.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 21:47               ` Ted Dennison
  2001-08-14  7:37                 ` Ole-Hjalmar Kristensen
@ 2001-08-14 13:22                 ` Marin David Condic
  2001-08-14 15:12                   ` Ted Dennison
  1 sibling, 1 reply; 41+ messages in thread
From: Marin David Condic @ 2001-08-14 13:22 UTC (permalink / raw)


This works nicely so long as you are doing one of two things (again, by
convention.) If you are always allocating your strings off the stack after
deciding how much space you need by entering a new scope or you are always
allocating your strings off the heap with the "new" operator. Both cases
allow you to write string handling code that takes advantage of 'First,
'Last, 'Length and so on.

However, this is not always convenient or simple. Certainly, understanding
the idioms necessary to do it is maybe just a bit beyond the beginner. (Hey,
there's a topic for the Idiom Guys!) Also, it is not something that is
assumed by all of the language supplied services. (Text_IO, being a problem
in this area. Suppose that a Get_Line were to return an access to a string
instead of putting characters into your own string and giving you a length?
That would have its own pitfalls, but it would allow you to structure
everything else using 'First 'Last & 'Length.)

Maybe Ada0x should attempt to establish some convention here? Ahhhhhh....
Skip it! We've got Unbounded strings - just use them!. :-)

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ted Dennison" <dennison@telepath.com> wrote in message
news:zVXd7.109$2u.23585@www.newsranger.com...
> It frees you from that problem in *some* cases. I find that most of the
time I
> don't change the string, so I can declare it perfectly sized. When you do
that,
> you are not storing the length explicitly, but rather implicitly in the
array
> bounds. As others have mentioned, you also don't have to iterate through
every
> valid data element to derive this piece of implicit information like you
do with
> C. Thus perfectly-sized Ada strings give you the best of both worlds.
>
> Unfortunately, the most notable exception to this is in reading data from
> Text_IO, which is also one of the first things a newbie will want to do
with Ada
> strings. :-(
>






^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  6:15                   ` James Rogers
@ 2001-08-14 14:03                     ` Warren W. Gay VE3WWG
  0 siblings, 0 replies; 41+ messages in thread
From: Warren W. Gay VE3WWG @ 2001-08-14 14:03 UTC (permalink / raw)


James Rogers wrote:
> "Warren W. Gay VE3WWG" wrote:
> > James Rogers wrote:
> > > An old saying is "there is no free lunch". In other words, nothing
> > > comes for free. In the case of a C string, you do not explicitly
> > > carry around the length of a string. Instead, you rely on a convention
> > > stating that the logical end of the string is indicated by a null
> > > character.
> > >
> > > The C approach presents two very real costs:
> > >
> > > 1) You must serially read the string to find the terminating null
> > >    character. This operation is very expensive if you only need to
> > >    determine the length of the string.
> >
> > To be honest, it works reasonably well for C/C++ because most strings in
> > a program tend to be short (of course this varies by application!) It would
> > be nice to have someone sample some Open Sourced packages and come
> > up with an average length, but I suspect that it would
> > be short enough. It is true for _some_ C strings/applications, that this
> > could be a significant overhead factor.
> 
> I would not like to make a claim about the "average" size of strings
> in C applications. I suspect the size varies quite a bit.

I was simply making a point, one which I am sure you understand. ;-)

> > > 2) Sometimes the null character is omitted. Since C arrays are
> > >    unbounded, this causes your program to read beyond the end of
> > >    the string until it finds a null character. The resulting
> > >    length will be incorrect.
> >
> > I'm not really wanting to support C/C++, but we should be careful
> > about what is being said here.. its really only a problem if you
> > _need_ a nul byte at the end. There are C programs that work with
> > fixed sized strings, like Ada, though this tends to be rarer (it
> > sometimes is done with embedded SQL/C). If you then need to pass
> > the fixed string to a printf() or other function that expects a
> > "C string", then yes, this then becomes a problem (just as it does
> > for Ada supplying a string for C).
> 
> The definition of a C string is a null terminated array of characters.
> C functions that do not require the null termination do not
> actually use strings. They merely use arrays of characters. This may
> seem like a subtle point, but it is critical. Functions expecting
> a C string for an argument absolutely rely on the existence of the
> nul byte at the end of the logical string.

Not all functions that a user writes, nor library functions actually 
require a nul byte, though I understand the concept of your "definition
of a C string". The function strncpy() is one obvious one where a nul 
byte is not essential.

> > One way to avoid this is to use a technique with strncpy() :
> >
> > #define BUF_LEN 8
> >
> > void
> > func(const char *in_str_with_maybe_no_null) {
> >    char my_buf[BUF_LEN];
> >
> >    strncpy(my_buf,in_str_with_maybe_no_null,BUF_LEN-1)[BUF_LEN-1] = 0;
> >
> > This restricts the copy to BUF_LEN-1 characters + 1 guaranteed nul byte.
> > It works because strncpy() the function, returns the (char *) pointer to
> > my_buf, resulting in the final assignment:
> >
> >    my_buf[BUF_LEN-1] = 0;
> >
> > You can do this in a much less cryptic way, but I have found it useful
> > in C programs, and it takes up less screen real-estate this way ;-)
> 
> And this approach assumes that copying only BUF_LEN characters will
> result is valid data. Sometimes it will. Sometimes BUF_LEN may be
> too small, resulting in a truncated string.

Absolutely, but that was not my point. In fact you can just as easily
have a loss of data with Ada's array slicing. ;-)

> > > Another less common cost occurs when copying C strings. The most
> > > efficient copy operation for C arrays is the memcpy function.
> > > This function allows you to copy blocks of memory efficiently.
> > > If you try to use memcpy to copy strings you will find some
> > > real problems. In those cases you want to copy the actual array
> > > of characters, not just the logical string contained in it.
> >
> > Have you said this in reverse? Normally you don't want to copy
> > anything beyond the nul byte, unless you're copying fixed length
> > arrays of characters, without treating nul as a special marker.
> 
> No, I am saying that strncpy() is less efficient than memcpy.

This very much dependant on how strncpy() is implemented. As a library
function, this could be implemented in assembly language for all
you know. Some CPU architectures (Z80 comes to mind) have single
instructions for dealing with this sort of thing. In these cases,
a limited strncpy() is definitely more efficient than memcpy(). The
single instruction is able to stop copying at the nul byte, but your
memcpy() is going to copy the whole array, whether it needs it or not.

> It is possible to make an exact copy of a string using memcpy.
> In fact the entire character array will be copied, not just the
> data up to the null.

Yes, but what's the advantage to that? If my string is 3 bytes out
of a maximum of 64 bytes, why would I want to copy the remaining
61 bytes that I would ignore?

> No, I am suggesting:
> 
> void my_func( char str[])
>    int slen = sizeof str; // which makes sense within the declaration
>                           // scope of the actual parameter.

OK, I see your point now.
-- 
Warren W. Gay VE3WWG
http://members.home.net/ve3wwg



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  9:54                   ` Lutz Donnerhacke
@ 2001-08-14 14:51                     ` James Rogers
  0 siblings, 0 replies; 41+ messages in thread
From: James Rogers @ 2001-08-14 14:51 UTC (permalink / raw)


Lutz Donnerhacke wrote:
> 
> * Ole-Hjalmar Kristensen wrote:
> >lutz@iks-jena.de (Lutz Donnerhacke) writes:
> >> It's not necessary to provide a buffer to hold any possible string of a
> >> given type if you can pass complex objects to or from a function. C can
> >> only pass primitive types and therefore switched to passing pointers of
> >> implicit terminated arrays.
> >
> >Close, but not quite. C will happily pass records by value.
> 
> Yep, interesting. Tested with a traditional compiler.
> 
> I wonder why C choosed to use inband signaling that heavily.
> They could use clear oob signaling for error signaling, array length ...
> But they don't. Why? Very strange.

You were almost correct in your earlier posting. The old K&R C did not
pass structs by value. That was an improvement added in ANSI C. 
The old K&R C could only pass primitives (int, float, double, 
etc and pointers) by value. The same restriction appeared for function
return values.

Jim Rogers
Colorado Springs, Colorado USA



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  7:37                 ` Ole-Hjalmar Kristensen
@ 2001-08-14 14:59                   ` Ted Dennison
  0 siblings, 0 replies; 41+ messages in thread
From: Ted Dennison @ 2001-08-14 14:59 UTC (permalink / raw)


In article <umq1ymf5byb.fsf@maestro.clustra.com>, Ole-Hjalmar Kristensen says...
>
>Ted Dennison<dennison@telepath.com> writes:
>
>> It frees you from that problem in *some* cases. I find that most of the time 
>> I don't change the string, so I can declare it perfectly sized. When you do 
>> that, you are not storing the length explicitly, but rather implicitly in 
>> the array bounds. As others have mentioned, you also don't have to iterate 
..
>But you usually don't need to know the length of the string, precisely
>because it has a sentinel value at the end :-)

OK. Now you are just being perverse. :-)

My point was, which is better: Not having to know the length because it is in a
sentinel value at the end, or not having to know the length because it is in an
attribute? Considering that the attribute can be read in one instruction
(sometimes, it will even be staticly available to the compiler), while the
sentinel must be laboriously searched for every time, I think the answer to this
question is quite clear.

>Perfectly-sized C string are no problems either:
>
>char x[] = "a perfect string";

True, they just do you no good. :-)   

>I was thinking of the case where you cannot statically allocate a
>perfectly sized string, which pops up whenever you have to get
>variable sized strings from somewhere, as you describe below.

Agreed. But its a *rare* case. Unfortunately, one of the places it pops up
regularly is in newbie code.

Also, I would not say that this issue "pops up whenever you have to get variable
size strings from somewhere". In intent, this statement is probably a tautology.
The only true "variable-sized" strings are those that you may need to modify
after creation for some reason. I find those quite rare, and in most cases
avoidable by simply creating new strings in which to store the modified version
of the old. 

I'd rather say that it pops when you are getting a string from some source and
the interface author (for whatever reason), didn't provide you a string-return
function interface. The other time it pops up is when you have to pass a string
upward or across scope boundries (it can't be localized to the scope in which
its length is decided), and the solution of doing a "new String'(watever)" is
undesirable for some reason. All other times you can do just fine by waiting to
declare the string until its length can be known. 

>Btw., I'm not saying that C strings are superior in general or trying
>to start a war, just that there are cases when using a sentinel value
>makes sense.

The only time I could see it making sense is when the only time you will ever
need to know a length is for terminating looping string operations. Even then,
the only advantage you have is that the length only needed one byte for its
encoding, rather than a full machine word. But even that slim advantage relies
on Ada's 'Range being dynamic, which is not always the case. In *every* other
case, it is an inferior solution.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14 13:22                 ` Marin David Condic
@ 2001-08-14 15:12                   ` Ted Dennison
  2001-08-14 15:33                     ` Marin David Condic
  0 siblings, 1 reply; 41+ messages in thread
From: Ted Dennison @ 2001-08-14 15:12 UTC (permalink / raw)


In article <9lb8mh$9am$1@nh.pace.co.uk>, Marin David Condic says...
>in this area. Suppose that a Get_Line were to return an access to a string
>instead of putting characters into your own string and giving you a length?

Actually, making it a function returning a String would be sufficient (and a
definite improvement). Its probably going to be a less efficient solution than
the buffer-length procedure though. That would probably put off a lot of people.
But it is rare that I'm doing I/O and sweating a few extra cycles (the wait for
the disk or the typing user is going to swamp most other considerations).

Martin Carlisle had a good solution for this, which is posted at AdaPower at
http://www.adapower.com/adacode.html. It uses recursion, but I don't think the
stack impact is much more than 2n where n is the string size.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14 15:12                   ` Ted Dennison
@ 2001-08-14 15:33                     ` Marin David Condic
  0 siblings, 0 replies; 41+ messages in thread
From: Marin David Condic @ 2001-08-14 15:33 UTC (permalink / raw)


Yeah, I've seen that trick before and it is really handy. Maybe a tad beyond
what you want to teach a raw beginner at first, but certainly not that
complex that it can't be used. Using it as a parameter to
To_Unbounded_String can pretty much eliminate any problems with arbitrary
limits or worrying about string sizes.

The real string handling trick should be to illustrate one or more idioms
for dealing with strings across a range of applications. Sort of saying "The
Ada Way(tm)" for handling strings is to read them this way, manipulate them
this way, then write them this way. An idiom should be given for the fixed
strings and for things like Unbounded. Id est, if you always read in a
string and immediately converted to Unbounded and wrote all string
parameters, etc, as Unbounded and used To_String when heading for output,
that is one idiom for apps where speed is not an issue. Another idiom would
be to read them as fixed strings, but dynamically allocate them, then write
all parameters to expect "String_Ptr.all" and use the attributes. Obviously,
an Ada app gains something by always treating strings in *some* consistent
manner. Many are possible. What ought to be the "preferred" way?

MDC
--
Marin David Condic
Senior Software Engineer
Pace Micro Technology Americas    www.pacemicro.com
Enabling the digital revolution
e-Mail:    marin.condic@pacemicro.com
Web:      http://www.mcondic.com/


"Ted Dennison" <dennison@telepath.com> wrote in message
news:Cdbe7.947$2u.26361@www.newsranger.com...
>
> Martin Carlisle had a good solution for this, which is posted at AdaPower
at
> http://www.adapower.com/adacode.html. It uses recursion, but I don't think
the
> stack impact is much more than 2n where n is the string size.
>






^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-14  9:38                 ` Ole-Hjalmar Kristensen
  2001-08-14  9:54                   ` Lutz Donnerhacke
@ 2001-08-14 16:44                   ` Darren New
  1 sibling, 0 replies; 41+ messages in thread
From: Darren New @ 2001-08-14 16:44 UTC (permalink / raw)


> Close, but not quite. C will happily pass records by value.

Not originally, tho. This was added later. (Still early on, yes, but not
originally.)

-- 
Darren New / Senior MTS & Free Radical / Invisible Worlds Inc.
San Diego, CA, USA (PST). Cryptokeys on demand. dnew@san.rr.com
           When was sliced bread invented?



^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-13 20:20               ` James Rogers
  2001-08-14  1:09                 ` Warren W. Gay VE3WWG
@ 2001-08-16 18:42                 ` Jay Nabonne
  2001-08-17  1:25                   ` Robert Dewar
  1 sibling, 1 reply; 41+ messages in thread
From: Jay Nabonne @ 2001-08-16 18:42 UTC (permalink / raw)



"James Rogers" <jimmaureenrogers@worldnet.att.net> wrote in message
news:3B783712.88029BB8@worldnet.att.net...
> Ole-Hjalmar Kristensen wrote:
> >
> > One thing which can be said in favour of having a terminator character
> > is that it frees you from having to store the length explicitly. The
> > length of a string is usually different from the size of the array
> > used to store the string.
> > So, in a sense a C string is more self-describing than a plain Ada
> > string.
> > Of course, as soon as you call a procedure, you can use a slice, but
> > you still need the actual length to decide which slice.
> >
> > On the balance, I would rather have Ada strings.
>
> An old saying is "there is no free lunch". In other words, nothing
> comes for free. In the case of a C string, you do not explicitly
> carry around the length of a string. Instead, you rely on a convention
> stating that the logical end of the string is indicated by a null
> character.
>
> The C approach presents two very real costs:
>
> 1) You must serially read the string to find the terminating null
>    character. This operation is very expensive if you only need to
>    determine the length of the string.
>
> 2) Sometimes the null character is omitted. Since C arrays are
>    unbounded, this causes your program to read beyond the end of
>    the string until it finds a null character. The resulting
>    length will be incorrect. When copying or editing a string
>    this problem will result in data corruption and undefined
>    behaviors.
>
> Another less common cost occurs when copying C strings. The most
> efficient copy operation for C arrays is the memcpy function.
> This function allows you to copy blocks of memory efficiently.
> If you try to use memcpy to copy strings you will find some
> real problems. In those cases you want to copy the actual array
> of characters, not just the logical string contained in it.
> The problem is that the C sizeof operator does not report the
> correct size of arrays outside the immediate scope where they
> are declared. Instead you will only get the size of the pointer
> to the first element of the array. Therefore, to efficiently
> copy C strings using memcpy you must provide a second "length"
> argument, which may not be readily available.
>
> Jim Rogers
> Colorado Springs, Colorado USA

A third occasional cost:

3) Strings that need to have null characters in them. It doesn't happen too
often, but if (under MS Windows) you ever want to read printer information
(the old way) or pass filter strings (e.g. "*.adb") to a file dialog, you
have to go through contortions to get a "string" that works.

-Jay Nabonne







^ permalink raw reply	[flat|nested] 41+ messages in thread

* Re: Ada Idioms Progress Preview
  2001-08-16 18:42                 ` Jay Nabonne
@ 2001-08-17  1:25                   ` Robert Dewar
  0 siblings, 0 replies; 41+ messages in thread
From: Robert Dewar @ 2001-08-17  1:25 UTC (permalink / raw)


"Jay Nabonne" <jay@rightagain.com> wrote in message news:<ZtUe7.1224$3T2.44851@news.pacbell.net>...
> "James Rogers" <jimmaureenrogers@worldnet.att.net> wrote in message
> news:3B783712.88029BB8@worldnet.att.net...
> > Ole-Hjalmar Kristensen wrote:
> > >
> > > One thing which can be said in favour of having a terminator character
> > > is that it frees you from having to store the length explicitly. 

Note that there is very little in the C core language that mandates
null-terminated strings (literals have a null character after them
and that's it). Really this convention is embodied in the library
routines, and of course it would be trivial to write a similar set
of routines in Ada for Ada use, and indeed even simpler, you can just
write a simple set of pragma import's and call the C routines directly.



^ permalink raw reply	[flat|nested] 41+ messages in thread

* C strings, was Re: Ada Idioms Progress Preview
  2001-08-14  1:09                 ` Warren W. Gay VE3WWG
  2001-08-14  6:15                   ` James Rogers
@ 2001-08-21  5:54                   ` David Thompson
  1 sibling, 0 replies; 41+ messages in thread
From: David Thompson @ 2001-08-21  5:54 UTC (permalink / raw)


Warren W. Gay VE3WWG <ve3wwg@home.com> wrote :
> .... There are C programs that work with
> fixed sized strings, like Ada, though this tends to be rarer (it
> sometimes is done with embedded SQL/C). If you then need to pass
> the fixed string to a printf() or other function that expects a
> "C string", then yes, this then becomes a problem (just as it does
> for Ada supplying a string for C).
>
Actually either truly fixed, or with (variable) length specified
by means other than null-termination such as a separate count.
That's an unfortunate example; for printf in particular, at least
for a data argument not the format string, this is easily handled
by the "precision" modifier e.g. %.20s or %.*s if variable.
For the many other library and user/3rd-party functions
expecting a C (null-terminated) string your point stands.
As discussed elsethread I believe, in C++ you also have
the option of std::string which effective keeps the separate
count and dynamically allocates for you, with methods and
standard functions thereon including converstion to C-string.

...
> OK, you're saying when you pass arrays into a C function, when
> the array is declared external to that function. Something like:
>
> void func2(char *str) {
>    // what is the array size of str?
> }
> void func1() {
>    char my_array[31];
>    func2(my_array);
> }
>
> This is a weakness, but if you know that func2() should work
> with fixed length arrays of a certain size, you can use:
>
> void func2(char str[31]) {
>    // what is the array size of str?
> }
>
> instead. However, I agree that this is feeble, compared to the
> way Ada passes array bounds information.
>
...
> OK, it sounds like you're suggesting the following:
>
> void my_func(char *str) {
>    int slen = sizeof str;    // which does not make sense
>
> But this is nonsense anyway - no self respecting C programmer would
> do this, because you are obviously asking for the size of the pointer ;-)
>
> However, if you declared this instead:
>
> void my_func(char str[31]) {
>    int array_len = sizeof str;  // this comes close to size of array
>
> (on many platforms : array_len=32 here due to padding)
>
NO!  In C (or C++) a function parameter declared apparently as an array
IS a pointer.  Any bound given is ignored <PEDANTIC>except that,
at least in C99, if the bound is constant and nonpositive it is clearly
a constraint violation, in C90 it was not clear if 6.7.1 adjustment
occurred before 6.1.2.5 array type nonempty, and wasn't
a mandatory diagnostic anyway; and in C99 if you specify
'static' in the brackets (its fourth! overloaded meaning),
you promise to call only with pointers that are in fact to arrays
of _at least_ that many elements, allowing some optimizations;
but even so:</>

The type IS pointer, and sizeof(str) IS that of pointer.
Full stop.  C FAQ 6.4, 6.21.

What you can do in C if you really want bounds matching is
void func2( char (*strp)[31]) {
  /* array is *strp elements are (*strp)[i] */
  /* sizeof(*strp) is 31 */
}
void func1(void) {
  char mystr[31]; char wrong[30];
  func2(&mystr); /* OK note & not usually used for "strings" */
  func2(&wrong); /* ERROR CAUGHT pointer mismatch */
}
This is effectively like classic Pascal.  Except for the pointer being
explicit, as it always is in C (and the C-like part of C++).

In C++ you can use a reference instead of a pointer,
and it does require matching of the array bound;
and/or templates that deduce the size of an array
(and usually inline to a call of a generic implementation
passing the bound explicitly).

However, where you do have a (nonparameter) array declaration,
sizeof the array is exactly sizeof one element times the bound.
There may be padding within a struct or union element (and
no rep clause to control it, though _some_ compiler have
nonportable options or pragmas), but NOT between elements
or at the end of an array.  And char in particular MUST
have sizeof 1 and minimal alignment.

--
- David.Thompson 1 now at worldnet.att.net








^ permalink raw reply	[flat|nested] 41+ messages in thread

end of thread, other threads:[~2001-08-21  5:54 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-03  4:16 Ada Idioms Progress Preview James Rogers
2001-08-03 19:45 ` Robert Dewar
2001-08-03 22:02   ` James Rogers
2001-08-06 22:33   ` Stanley R. Allen
2001-08-07  2:45     ` tmoran
2001-08-07 12:15       ` Larry Kilgallen
2001-08-07 13:26         ` Philip Anderson
2001-08-08  2:23         ` Robert Dewar
2001-08-08  5:58           ` Ehud Lamm
2001-08-08  2:19       ` Robert Dewar
2001-08-08 15:13         ` Ted Dennison
2001-08-08 18:03           ` tmoran
2001-08-09 20:36           ` Florian Weimer
2001-08-10 21:02         ` Jay Nabonne
2001-08-10 21:51           ` Larry Kilgallen
2001-08-13 14:19             ` Ted Dennison
2001-08-13 14:05           ` Ted Dennison
2001-08-13 14:19             ` Marin David Condic
2001-08-13 15:47             ` Ole-Hjalmar Kristensen
2001-08-13 16:22               ` Marin David Condic
2001-08-13 18:48               ` Larry Kilgallen
2001-08-14  7:05                 ` Ole-Hjalmar Kristensen
2001-08-13 20:20               ` James Rogers
2001-08-14  1:09                 ` Warren W. Gay VE3WWG
2001-08-14  6:15                   ` James Rogers
2001-08-14 14:03                     ` Warren W. Gay VE3WWG
2001-08-21  5:54                   ` C strings, was " David Thompson
2001-08-16 18:42                 ` Jay Nabonne
2001-08-17  1:25                   ` Robert Dewar
2001-08-13 21:47               ` Ted Dennison
2001-08-14  7:37                 ` Ole-Hjalmar Kristensen
2001-08-14 14:59                   ` Ted Dennison
2001-08-14 13:22                 ` Marin David Condic
2001-08-14 15:12                   ` Ted Dennison
2001-08-14 15:33                     ` Marin David Condic
2001-08-14  8:49               ` Lutz Donnerhacke
2001-08-14  9:38                 ` Ole-Hjalmar Kristensen
2001-08-14  9:54                   ` Lutz Donnerhacke
2001-08-14 14:51                     ` James Rogers
2001-08-14 16:44                   ` Darren New
2001-08-14  1:39             ` Slicing ( Ada Idioms Progress Preview ) Warren W. Gay VE3WWG

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox