From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,45b47ecb995e7a3 X-Google-Attributes: gid103376,public X-Google-ArrivalTime: 2001-08-14 07:03:09 PST Path: archiver1.google.com!newsfeed.google.com!sn-xit-02!supernews.com!newsfeed.direct.ca!look.ca!news1.tor.metronet.ca!nnrp1.tor.metronet.ca!not-for-mail Message-ID: <3B792F9C.49A0FC7D@home.com> From: "Warren W. Gay VE3WWG" X-Mailer: Mozilla 4.75 [en] (Windows NT 5.0; U) X-Accept-Language: en MIME-Version: 1.0 Newsgroups: comp.lang.ada Subject: Re: Ada Idioms Progress Preview References: <3B6F1B2F.4FC3C833@gsde.hou.us.ray.com> <5ee5b646.0108071819.6e84e33d@posting.google.com> <3_Xc7.45$NM5.84779@news.pacbell.net> <3B783712.88029BB8@worldnet.att.net> <3B787A30.F806DB00@home.com> <3B78C290.4DD088A8@worldnet.att.net> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Tue, 14 Aug 2001 14:03:08 GMT NNTP-Posting-Host: 198.96.47.195 NNTP-Posting-Date: Tue, 14 Aug 2001 08:03:08 MDT Organization: MetroNet Communications Group Inc. Xref: archiver1.google.com comp.lang.ada:11914 Date: 2001-08-14T14:03:08+00:00 List-Id: 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