Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #163436 > unrolled thread
| Started by | pozz <pozzugno@gmail.com> |
|---|---|
| First post | 2021-11-17 11:36 +0100 |
| Last post | 2021-11-20 20:49 -0800 |
| Articles | 20 on this page of 48 — 16 participants |
Back to article view | Back to comp.lang.c
Automatic strings without malloc pozz <pozzugno@gmail.com> - 2021-11-17 11:36 +0100
Re: Automatic strings without malloc pozz <pozzugno@gmail.com> - 2021-11-17 11:38 +0100
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-17 03:00 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-17 12:04 +0100
Re: Automatic strings without malloc Manfred <noname@add.invalid> - 2021-11-17 18:19 +0100
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-17 20:34 +0100
Re: Automatic strings without malloc pozz <pozzugno@gmail.com> - 2021-11-18 10:07 +0100
Re: Automatic strings without malloc Thiago Adams <thiago.adams@gmail.com> - 2021-11-17 05:11 -0800
Re: Automatic strings without malloc Philipp Klaus Krause <pkk@spth.de> - 2021-11-18 15:29 +0100
Re: Automatic strings without malloc Bart <bc@freeuk.com> - 2021-11-17 13:47 +0000
Re: Automatic strings without malloc scott@slp53.sl.home (Scott Lurndal) - 2021-11-17 15:34 +0000
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-17 07:36 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-17 16:56 +0100
Re: Automatic strings without malloc scott@slp53.sl.home (Scott Lurndal) - 2021-11-17 18:21 +0000
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-17 20:37 +0100
Re: Automatic strings without malloc scott@slp53.sl.home (Scott Lurndal) - 2021-11-17 21:35 +0000
Re: Automatic strings without malloc Thiago Adams <thiago.adams@gmail.com> - 2021-11-19 05:38 -0800
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-19 07:13 -0800
Re: Automatic strings without malloc William Ahern <william@25thandClement.com> - 2021-11-17 20:46 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-18 10:50 +0100
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-18 03:56 -0800
Re: Automatic strings without malloc Thiago Adams <thiago.adams@gmail.com> - 2021-11-18 05:54 -0800
Re: Automatic strings without malloc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-18 16:38 +0000
Re: Automatic strings without malloc Thiago Adams <thiago.adams@gmail.com> - 2021-11-18 10:52 -0800
Re: Automatic strings without malloc Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-18 11:27 -0800
Re: Automatic strings without malloc Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-11-18 20:41 +0000
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-18 16:05 +0100
Re: Automatic strings without malloc Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-17 11:22 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-17 20:39 +0100
Re: Automatic strings without malloc Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-17 15:18 -0800
[OT] Generally... [Was: Automatic strings without malloc] Jeremy Brubaker <jbrubake@orionarts.invalid> - 2021-11-18 17:46 +0000
Re: [OT] Generally... [Was: Automatic strings without malloc] Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-18 11:21 -0800
Re: Automatic strings without malloc Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-11-17 11:14 -0800
Re: Automatic strings without malloc pozz <pozzugno@gmail.com> - 2021-11-18 10:08 +0100
Re: Automatic strings without malloc Siri Cruise <chine.bleu@yahoo.com> - 2021-11-18 12:25 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-18 23:19 +0100
Re: Automatic strings without malloc Siri Cruise <chine.bleu@yahoo.com> - 2021-11-18 17:22 -0800
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-19 01:46 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-19 17:29 +0100
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-19 17:26 +0100
Re: Automatic strings without malloc Siri Cruise <chine.bleu@yahoo.com> - 2021-11-19 09:00 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-19 18:25 +0100
Re: Automatic strings without malloc "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-19 14:58 -0800
Re: Automatic strings without malloc Guillaume <message@bottle.org> - 2021-11-19 19:37 +0100
Re: Automatic strings without malloc "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2021-11-19 12:34 -0800
Re: Automatic strings without malloc Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2021-11-19 13:44 -0800
Re: Automatic strings without malloc David Brown <david.brown@hesbynett.no> - 2021-11-20 13:30 +0100
Re: Automatic strings without malloc luser droog <luser.droog@gmail.com> - 2021-11-20 20:49 -0800
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2021-11-18 03:56 -0800 |
| Message-ID | <20b9b695-32b8-4361-b88a-38d041950994n@googlegroups.com> |
| In reply to | #163464 |
On Thursday, 18 November 2021 at 09:50:36 UTC, David Brown wrote: > On 18/11/2021 05:46, William Ahern wrote: > > David Brown <david...@hesbynett.no> wrote: > >> On 17/11/2021 19:21, Scott Lurndal wrote: > >>> David Brown <david...@hesbynett.no> writes: > >>>> On 17/11/2021 16:36, Malcolm McLean wrote: > >>>>> On Wednesday, 17 November 2021 at 15:34:50 UTC, Scott Lurndal wrote: > >>>>>> pozz <pozz...@gmail.com> writes: > >>>>>>> Many times I need to construct a string through a call to sprintf and > >>>>>>> pass it to an external function. > >>>>>>> > >>>>>>> char s[32]; > >>>>>>> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year); > >>>>>>> lcd_write(s); > >>>>>> One might consider using 'snprintf' instead of 'sprintf'; it is a bit safer. > >>>>>> > >>>>> It depends whether wrong results are better or worse than no results. > >>>>> > >>>> > >>>> Generally, a truncated string on the output is better than a stack > >>>> overflow with your embedded system crashing or going wild. But your > >>>> needs may vary. > >>> > >>> Indeed. Plus a good programmer checks the return value from snprintf. > >>> Always. > >>> > >> > >> Really? I never do. But I make sure my buffers are the right size for > >> the job - or that it doesn't matter if there is truncation (such as for > >> log outputs). I prefer to be sure that my inputs to the function are > >> correct, than to call the function and check for problems afterwards. > >> (Different people can have different requirements here - but that's the > >> way I do it.) > >> > > > > That is generally the best approach, but doesn't work well with snprintf (or > > stringification of data types generally), especially in light of the express > > concern about robustness to drive-by edits of the format string. > > > It works perfectly well in the type of programming I do. Different > kinds of work have different requirements. In small-systems embedded > programming (which is what I usually work with, and also what the OP is > doing), you know what you are passing to your printf type functions. > You know what the output is connected to (a screen, a UART, a log in > flash, etc.). > > But it can be an entirely different matter in other kinds of programming > where you might have the format string coming from an external file of > translations made by a third party, or the endless variety of > complicating factors that can occur on big systems. Scott could be > right that a good programmer always checks the return value of snprintf > when doing the kind of coding he does - but it is not right for the kind > of coding /I/ do. > I tend to use C++ for strings because C++ strings are assignable, destructible, returnable, and C++ manages the buffer. C isn't a good language for doing string processing in (though it is a good language for implementing string processing algorithms themselves in). > > > The way to avoid string buffer errors is to avoid strings and stick to > > concrete data types or to process data in a rigorously streaming fashion. > The way to avoid string buffer errors is the same as you avoid any other > errors - good development practices. That runs the whole gamut from > high level concerns to low-level details. It includes making sure you > have clear specifications for the code you are writing, making sure the > programmer is appropriately qualified, having code review practices, > testing regimes, automatic checking tools, making sure the data coming > into your code is appropriate, making sure you correctly handle all > cases (including worst cases and pathological cases), and so on. It's > just like any other coding error. > This all costs money, it demands management skills and resources the company may not have, and it can lead to programmers feeling over-managed. A very important factor is the testability of the code, and the consequences of an error. You can over-engineer processes as well as actual code.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2021-11-18 05:54 -0800 |
| Message-ID | <3b101498-3f74-4089-86ba-7ae728824e3en@googlegroups.com> |
| In reply to | #163466 |
On Thursday, November 18, 2021 at 8:57:04 AM UTC-3, Malcolm McLean wrote:
> On Thursday, 18 November 2021 at 09:50:36 UTC, David Brown wrote:
> > On 18/11/2021 05:46, William Ahern wrote:
> > > David Brown <david...@hesbynett.no> wrote:
> > >> On 17/11/2021 19:21, Scott Lurndal wrote:
> > >>> David Brown <david...@hesbynett.no> writes:
> > >>>> On 17/11/2021 16:36, Malcolm McLean wrote:
> > >>>>> On Wednesday, 17 November 2021 at 15:34:50 UTC, Scott Lurndal wrote:
> > >>>>>> pozz <pozz...@gmail.com> writes:
> > >>>>>>> Many times I need to construct a string through a call to sprintf and
> > >>>>>>> pass it to an external function.
> > >>>>>>>
> > >>>>>>> char s[32];
> > >>>>>>> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year);
> > >>>>>>> lcd_write(s);
> > >>>>>> One might consider using 'snprintf' instead of 'sprintf'; it is a bit safer.
> > >>>>>>
> > >>>>> It depends whether wrong results are better or worse than no results.
> > >>>>>
> > >>>>
> > >>>> Generally, a truncated string on the output is better than a stack
> > >>>> overflow with your embedded system crashing or going wild. But your
> > >>>> needs may vary.
> > >>>
> > >>> Indeed. Plus a good programmer checks the return value from snprintf.
> > >>> Always.
> > >>>
> > >>
> > >> Really? I never do. But I make sure my buffers are the right size for
> > >> the job - or that it doesn't matter if there is truncation (such as for
> > >> log outputs). I prefer to be sure that my inputs to the function are
> > >> correct, than to call the function and check for problems afterwards.
> > >> (Different people can have different requirements here - but that's the
> > >> way I do it.)
> > >>
> > >
> > > That is generally the best approach, but doesn't work well with snprintf (or
> > > stringification of data types generally), especially in light of the express
> > > concern about robustness to drive-by edits of the format string.
> > >
> > It works perfectly well in the type of programming I do. Different
> > kinds of work have different requirements. In small-systems embedded
> > programming (which is what I usually work with, and also what the OP is
> > doing), you know what you are passing to your printf type functions.
> > You know what the output is connected to (a screen, a UART, a log in
> > flash, etc.).
> >
> > But it can be an entirely different matter in other kinds of programming
> > where you might have the format string coming from an external file of
> > translations made by a third party, or the endless variety of
> > complicating factors that can occur on big systems. Scott could be
> > right that a good programmer always checks the return value of snprintf
> > when doing the kind of coding he does - but it is not right for the kind
> > of coding /I/ do.
> >
> I tend to use C++ for strings because C++ strings are assignable, destructible,
> returnable, and C++ manages the buffer. C isn't a good language for doing
> string processing in (though it is a good language for implementing string
> processing algorithms themselves in).
I moved from C++ to C and I don't miss std::string. Quite the opposite, I don't feel
comfortable using std::string/std::wstring anymore even in C++.
One problem of std::string tries to do two different jobs at the same time
using the same object. One job is "string builder" and a the other "string holder"
Using std::string as string holder is a waste of memory. For instance:
std::map<std::string, something>
Map doesn't want build string, it just need to hold a string.
Another bad thing about std::string is to have to use .c_str() to make
it compatible with C strings. Clearly std::string is not a built-in
language string. "literals" are not std::string.
void F1(std::string s);
void F2(const std::string& s);
F("this is very bad because heap is used");
F("this is also very bad heap is used");
I have being using std::wstring for a long time. When moving to C
everything in my code is char* and it means UTF8. Life is so much
easier with much less conversions. It is amazing how few function we
need to work with UTF8. The same existing function can be used.
For instance, strcat is fine, strlen (if you need byte len), strdup etc.. everything just works.
u8"utf encoded" also completes the task.
What is missing. Because I create windows programs I miss the open_memstream.
This is for the job of "build strings" and to use the same FILE* functions.
So in C:
const char * or char * to represent and hold strings.
snprintf and open_memstream to build (and format) strings.
Dangerous parts...
strncpy because may not add NULL. ( I have heart of strlcpy )
replacement .
object->text = strdup("new text"); //this may cause a leak
especially for this replacement problem I think C++ has an advantage.
Something I use this that free the previous string.
replace_string(&object->text, strdup("new text"));
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-11-18 16:38 +0000 |
| Message-ID | <87y25lmnat.fsf@bsb.me.uk> |
| In reply to | #163467 |
Thiago Adams <thiago.adams@gmail.com> writes: > One problem of std::string tries to do two different jobs at the same > time using the same object. One job is "string builder" and a the > other "string holder" > > Using std::string as string holder is a waste of memory. For instance: > std::map<std::string, something> > Map doesn't want build string, it just need to hold a string. Why would you write that if you wanted just to reference the strings? You'd use std::map<std::string &, something>, or similar. Your builder/holder distinction is unclear to me. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | Thiago Adams <thiago.adams@gmail.com> |
|---|---|
| Date | 2021-11-18 10:52 -0800 |
| Message-ID | <4372cb8c-3bf0-40b3-bb9d-eece1a4241dcn@googlegroups.com> |
| In reply to | #163476 |
On Thursday, November 18, 2021 at 1:38:46 PM UTC-3, Ben Bacarisse wrote: > Thiago Adams <thiago...@gmail.com> writes: > > > One problem of std::string tries to do two different jobs at the same > > time using the same object. One job is "string builder" and a the > > other "string holder" > > > > Using std::string as string holder is a waste of memory. For instance: > > std::map<std::string, something> > > Map doesn't want build string, it just need to hold a string. > Why would you write that if you wanted just to reference the strings? > You'd use std::map<std::string &, something>, or similar. Your > builder/holder distinction is unclear to me. We can create a map<const char*, something> or create a small string class RAII for it. But this is a workaround and represents exceptions of usage and more rules. (when use/not to use std::string) If you try std::map<std::string &, something> then a lot of operations will become different. e.g std::map<std::string&, X> map; map["a"] = X(1); will give you 10 lines of error. If you have a map of references the string must live in some place. They must live more than the map. I never tried to do this, but now just to see what happens it is hard to make it work. https://godbolt.org/z/r95M1Tn6W >Your builder/holder distinction is unclear to me. If std::string wants to build the string (manage the size and allocation/deallocation) concatenate string using += + etc.. more data is necessary. For instance, the capacity of the buffer is also included inside the string object. On the other hand, if you have a string just to hold a string (like char*) this is enough for a key in a map and we will never need concatenated etc this object after its creation. So it is waste of memory. Even size is not necessary in this case.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-18 11:27 -0800 |
| Message-ID | <87h7c9p8ln.fsf@nosuchdomain.example.com> |
| In reply to | #163480 |
Thiago Adams <thiago.adams@gmail.com> writes:
> On Thursday, November 18, 2021 at 1:38:46 PM UTC-3, Ben Bacarisse wrote:
>> Thiago Adams <thiago...@gmail.com> writes:
>>
>> > One problem of std::string tries to do two different jobs at the same
>> > time using the same object. One job is "string builder" and a the
>> > other "string holder"
>> >
>> > Using std::string as string holder is a waste of memory. For instance:
>> > std::map<std::string, something>
>> > Map doesn't want build string, it just need to hold a string.
>> Why would you write that if you wanted just to reference the strings?
>> You'd use std::map<std::string &, something>, or similar. Your
>> builder/holder distinction is unclear to me.
>
> We can create a map<const char*, something> or create a small
> string class RAII for it. But this is a workaround and represents
> exceptions of usage and more rules. (when use/not to use std::string)
Two const char* values can be unequal but refer to the same string value.
[...]
> On the other hand, if you have a string just to hold a string (like
> char*) this is enough for a key in a map and we will never need
> concatenated etc this object after its creation. So it is waste of
> memory. Even size is not necessary in this case.
A char* value doesn't *hold* a string, it *refers to* a string. And a C
string, unlike a C++ std::string, cannot contain null characters (which
may well be perfectly ok for most applications).
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2021-11-18 20:41 +0000 |
| Message-ID | <87ee7dmc1l.fsf@bsb.me.uk> |
| In reply to | #163480 |
Thiago Adams <thiago.adams@gmail.com> writes: > On Thursday, November 18, 2021 at 1:38:46 PM UTC-3, Ben Bacarisse wrote: >> Thiago Adams <thiago...@gmail.com> writes: >> >> > One problem of std::string tries to do two different jobs at the same >> > time using the same object. One job is "string builder" and a the >> > other "string holder" >> > >> > Using std::string as string holder is a waste of memory. For instance: >> > std::map<std::string, something> >> > Map doesn't want build string, it just need to hold a string. >> Why would you write that if you wanted just to reference the strings? >> You'd use std::map<std::string &, something>, or similar. Your >> builder/holder distinction is unclear to me. > > We can create a map<const char*, something> or create a small > string class RAII for it. But this is a workaround and represents > exceptions of usage and more rules. (when use/not to use std::string) That's not my view. It makes what you mean explicit. You either copy to string into the map or you reference it. Whatever it you do in C will be (logically) one or the other, but it won't be explicit -- at least not in the type itself. > If you try std::map<std::string &, something> then a lot of operations will > become different. > > e.g > > std::map<std::string&, X> map; > map["a"] = X(1); > > will give you 10 lines of error. Yes, sorry. I meant to suggest a pointer. You can't use (raw) references in maps. -- Ben.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-18 16:05 +0100 |
| Message-ID | <sn5q39$v8d$1@dont-email.me> |
| In reply to | #163466 |
On 18/11/2021 12:56, Malcolm McLean wrote: > On Thursday, 18 November 2021 at 09:50:36 UTC, David Brown wrote: >> On 18/11/2021 05:46, William Ahern wrote: > I tend to use C++ for strings because C++ strings are assignable, destructible, > returnable, and C++ manages the buffer. C isn't a good language for doing > string processing in (though it is a good language for implementing string > processing algorithms themselves in). None of that is the slightest help to the OP. C++ classes that manage dynamic memory are easier to get right than manual memory management in C - but there are still useless if you want (with good reason) to avoid any use of heap memory. >> >>> The way to avoid string buffer errors is to avoid strings and stick to >>> concrete data types or to process data in a rigorously streaming fashion. >> The way to avoid string buffer errors is the same as you avoid any other >> errors - good development practices. That runs the whole gamut from >> high level concerns to low-level details. It includes making sure you >> have clear specifications for the code you are writing, making sure the >> programmer is appropriately qualified, having code review practices, >> testing regimes, automatic checking tools, making sure the data coming >> into your code is appropriate, making sure you correctly handle all >> cases (including worst cases and pathological cases), and so on. It's >> just like any other coding error. >> > This all costs money, it demands management skills and resources > the company may not have, and it can lead to programmers feeling > over-managed. You pick details that match the needs of the project and the capabilities of the company. A small company might not have a large enough programming team to make code reviews possible. The quality control you need for a simple desktop program is going to be different from what you need for controlling a car engine. And so on. > A very important factor is the testability of the code, and the consequences > of an error. You can over-engineer processes as well as actual code. > Of course. Lots of bugs have occurred by people putting in "just in case" test code that is untestable in the lab, but fails at some point after deployment.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-17 11:22 -0800 |
| Message-ID | <87tugapoxu.fsf@nosuchdomain.example.com> |
| In reply to | #163447 |
David Brown <david.brown@hesbynett.no> writes:
> On 17/11/2021 16:36, Malcolm McLean wrote:
>> On Wednesday, 17 November 2021 at 15:34:50 UTC, Scott Lurndal wrote:
>>> pozz <pozz...@gmail.com> writes:
>>>> Many times I need to construct a string through a call to sprintf and
>>>> pass it to an external function.
>>>>
>>>> char s[32];
>>>> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year);
>>>> lcd_write(s);
>>> One might consider using 'snprintf' instead of 'sprintf'; it is a bit safer.
>>>
>> It depends whether wrong results are better or worse than no results.
>
> Generally, a truncated string on the output is better than a stack
> overflow with your embedded system crashing or going wild. But your
> needs may vary.
Sure, truncation is probably better than undefined behavior, but
depending on the context it might not be *much* better.
For a small LCD display, truncation is probably the best fallback
(followed by thinking about how to make the message fit). On the other
hand, truncating "rm -rf /home/user/temp_dir" to "rm -rf /home/user" is
likely to be far worse than crashing the program.
There's no general rule other than that you should always *think*
about what will/should happen if there's not enough room in the target
array.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-17 20:39 +0100 |
| Message-ID | <sn3lq4$qhj$4@dont-email.me> |
| In reply to | #163451 |
On 17/11/2021 20:22, Keith Thompson wrote: > David Brown <david.brown@hesbynett.no> writes: >> On 17/11/2021 16:36, Malcolm McLean wrote: >>> On Wednesday, 17 November 2021 at 15:34:50 UTC, Scott Lurndal wrote: >>>> pozz <pozz...@gmail.com> writes: >>>>> Many times I need to construct a string through a call to sprintf and >>>>> pass it to an external function. >>>>> >>>>> char s[32]; >>>>> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year); >>>>> lcd_write(s); >>>> One might consider using 'snprintf' instead of 'sprintf'; it is a bit safer. >>>> >>> It depends whether wrong results are better or worse than no results. >> >> Generally, a truncated string on the output is better than a stack >> overflow with your embedded system crashing or going wild. But your >> needs may vary. > > Sure, truncation is probably better than undefined behavior, but > depending on the context it might not be *much* better. > > For a small LCD display, truncation is probably the best fallback > (followed by thinking about how to make the message fit). On the other > hand, truncating "rm -rf /home/user/temp_dir" to "rm -rf /home/user" is > likely to be far worse than crashing the program. Yes - "generally" does not mean "always" ! That's a good example of when truncation could be rather bad. > > There's no general rule other than that you should always *think* > about what will/should happen if there's not enough room in the target > array. > Alternatively, think about how to ensure that there /always/ will be enough room in the target array. Either way, always /think/.
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-17 15:18 -0800 |
| Message-ID | <87pmqype0g.fsf@nosuchdomain.example.com> |
| In reply to | #163454 |
David Brown <david.brown@hesbynett.no> writes:
> On 17/11/2021 20:22, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 17/11/2021 16:36, Malcolm McLean wrote:
>>>> On Wednesday, 17 November 2021 at 15:34:50 UTC, Scott Lurndal wrote:
>>>>> pozz <pozz...@gmail.com> writes:
>>>>>> Many times I need to construct a string through a call to sprintf and
>>>>>> pass it to an external function.
>>>>>>
>>>>>> char s[32];
>>>>>> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year);
>>>>>> lcd_write(s);
>>>>> One might consider using 'snprintf' instead of 'sprintf'; it is a bit safer.
>>>>>
>>>> It depends whether wrong results are better or worse than no results.
>>>
>>> Generally, a truncated string on the output is better than a stack
>>> overflow with your embedded system crashing or going wild. But your
>>> needs may vary.
>>
>> Sure, truncation is probably better than undefined behavior, but
>> depending on the context it might not be *much* better.
>>
>> For a small LCD display, truncation is probably the best fallback
>> (followed by thinking about how to make the message fit). On the other
>> hand, truncating "rm -rf /home/user/temp_dir" to "rm -rf /home/user" is
>> likely to be far worse than crashing the program.
>
> Yes - "generally" does not mean "always" ! That's a good example of
> when truncation could be rather bad.
Depending on the context, "generally" can mean either "usually" or
"always". I've found that people generally interpret it in the most
inconvenient way possible.
>> There's no general rule other than that you should always *think*
>> about what will/should happen if there's not enough room in the target
>> array.
>
> Alternatively, think about how to ensure that there /always/ will be
> enough room in the target array. Either way, always /think/.
That's not always possible, especially if the "array" is a display
device. But yes, "always think" is a good idea. I think.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Jeremy Brubaker <jbrubake@orionarts.invalid> |
|---|---|
| Date | 2021-11-18 17:46 +0000 |
| Subject | [OT] Generally... [Was: Automatic strings without malloc] |
| Message-ID | <sn63ij$9j2$1@dont-email.me> |
| In reply to | #163458 |
On 2021-11-17, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote: > > Depending on the context, "generally" can mean either "usually" or > "always". I've found that people generally interpret it in the most > inconvenient way possible. So, do you mean that people *usually* interpret it in the most inconvenient way possible or that people *always* interpret it in the most inconvenient way possible? I find that generally people can be very imprecise with their language. -- Jeremy Brubaker
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-18 11:21 -0800 |
| Subject | Re: [OT] Generally... [Was: Automatic strings without malloc] |
| Message-ID | <87lf1lp8vf.fsf@nosuchdomain.example.com> |
| In reply to | #163478 |
Jeremy Brubaker <jbrubake@orionarts.invalid> writes:
> On 2021-11-17, Keith Thompson <Keith.S.Thompson+u@gmail.com> wrote:
>>
>> Depending on the context, "generally" can mean either "usually" or
>> "always". I've found that people generally interpret it in the most
>> inconvenient way possible.
>
> So, do you mean that people *usually* interpret it in the most
> inconvenient way possible or that people *always* interpret it in the
> most inconvenient way possible?
Yes.
> I find that generally people can be very imprecise with their language.
Yes.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
|---|---|
| Date | 2021-11-17 11:14 -0800 |
| Message-ID | <87lf1mvbl5.fsf@nosuchdomain.example.com> |
| In reply to | #163436 |
pozz <pozzugno@gmail.com> writes:
> Many times I need to construct a string through a call to sprintf and
> pass it to an external function.
>
> char s[32];
> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year);
> lcd_write(s);
I presume that lcd_write() doesn't retain the address passed to it, so the
display won't be messed up when the array object s ceases to exist.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips
void Void(void) { Void(); } /* The recursive call of the void */
[toc] | [prev] | [next] | [standalone]
| From | pozz <pozzugno@gmail.com> |
|---|---|
| Date | 2021-11-18 10:08 +0100 |
| Message-ID | <sn555j$cjo$2@dont-email.me> |
| In reply to | #163450 |
Il 17/11/2021 20:14, Keith Thompson ha scritto: > pozz <pozzugno@gmail.com> writes: >> Many times I need to construct a string through a call to sprintf and >> pass it to an external function. >> >> char s[32]; >> sprintf(s, "Hi %s, today is %d/%d/%d", yourname, day, month, year); >> lcd_write(s); > > I presume that lcd_write() doesn't retain the address passed to it, so the > display won't be messed up when the array object s ceases to exist. Yes of course
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2021-11-18 12:25 -0800 |
| Message-ID | <chine.bleu-14C4A8.12251018112021@reader.eternal-september.org> |
| In reply to | #163436 |
In article <sn2lvp$sl7$1@dont-email.me>,
pozz <pozzugno@gmail.com> wrote:
> Many times I need to construct a string through a call to sprintf and
> pass it to an external function.
If it's too crippled to have malloc, you can do your own. Many
systems have blank common or bss after the end of all memory
initialised with code and data. You might even have the extern
address 'edata' for the bss start and 'end' for bss end. If so
you can use that as a heap:
void *heap = edata, *heapend = end;
If all else fails, use the load map to determine the maximum N
char heap[N]; char *heapend = heap+N;
with cc -DN=biggestthatloads ...
Once you got your heap area, you can do something cheap like
void *marker = 0;
void *mark (size_t n) {
void *address = marker ? marker : heap;
if (address+n>=heapend) return 0;
marker = address+n; return address;
}
void release (void *address) {
marker = address;
}
....
char *s = mark(strlen(yourname)
+strlen("Hi %s, today is %d/%d/%d"_
+4+2+2+1;
sprintf(s, "Hi %s, today is %d/%d/%d",
yourname, day, month, year);
lcd_write(s);
/*string no longer needed*/release(s);
--
:-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @
'I desire mercy, not sacrifice.' /|\
Discordia: not just a religion but also a parody. This post / \
I am an Andrea Doria sockpuppet. insults Islam. Mohammed
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-18 23:19 +0100 |
| Message-ID | <sn6jgl$val$1@dont-email.me> |
| In reply to | #163484 |
On 18/11/2021 21:25, Siri Cruise wrote: > In article <sn2lvp$sl7$1@dont-email.me>, > pozz <pozzugno@gmail.com> wrote: > >> Many times I need to construct a string through a call to sprintf and >> pass it to an external function. > > If it's too crippled to have malloc, you can do your own. Many > systems have blank common or bss after the end of all memory > initialised with code and data. You might even have the extern > address 'edata' for the bss start and 'end' for bss end. If so > you can use that as a heap: It is not a matter of a system not having "malloc" and a heap - it is a matter of deciding not to use it. In small systems with limited ram and no paging mechanisms, it is quite realistic to either run out of heap space or - worse, since it is harder to find by testing - for heap fragmentation to mean that memory allocations may fail as there is not enough consecutive free space. And in embedded systems, failure to get the memory you need often means failure of the system - the device does not do its job. Thus a 0 return from malloc can be as bad as a string buffer overflow or any other error - the system is broken, the car crashes, the microwave burns your food, the washing machine eats your socks. And while you can avoid the string buffer overflow by making sure your buffer is large enough and your string is limited in length, making sure your heap can /never/ get fragmented is typically either extremely difficult, or impossible. The solution is to avoid dynamic memory in any situation where failure to get the memory is not tolerable.
[toc] | [prev] | [next] | [standalone]
| From | Siri Cruise <chine.bleu@yahoo.com> |
|---|---|
| Date | 2021-11-18 17:22 -0800 |
| Message-ID | <chine.bleu-8C3BBF.17221518112021@reader.eternal-september.org> |
| In reply to | #163487 |
In article <sn6jgl$val$1@dont-email.me>, David Brown <david.brown@hesbynett.no> wrote: > It is not a matter of a system not having "malloc" and a heap - it is a > matter of deciding not to use it. In small systems with limited ram and So you cut off your hand and now you want to be told how to fashion a hook. Got it. Good luck. -- :-<> Siri Seal of Disavowal #000-001. Disavowed. Denied. Deleted. @ 'I desire mercy, not sacrifice.' /|\ Discordia: not just a religion but also a parody. This post / \ I am an Andrea Doria sockpuppet. insults Islam. Mohammed
[toc] | [prev] | [next] | [standalone]
| From | Malcolm McLean <malcolm.arthur.mclean@gmail.com> |
|---|---|
| Date | 2021-11-19 01:46 -0800 |
| Message-ID | <736b2fc6-91b9-4ef7-8f03-1aa662a9f86fn@googlegroups.com> |
| In reply to | #163488 |
On Friday, 19 November 2021 at 01:22:36 UTC, Siri Cruise wrote: > In article <sn6jgl$val$1...@dont-email.me>, > David Brown <david...@hesbynett.no> wrote: > > > It is not a matter of a system not having "malloc" and a heap - it is a > > matter of deciding not to use it. In small systems with limited ram and > So you cut off your hand and now you want to be told how to > fashion a hook. Got it. Good luck. > David Brown probably didn't take the decision himself not to use malloc. Dynamic memory is often banned, by over-all coding requirements that are decided upon by senior mangement or customers. The question then is what to do when you have a string whose length isn't known at compile time.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-19 17:29 +0100 |
| Message-ID | <sn8jd6$ejj$2@dont-email.me> |
| In reply to | #163489 |
On 19/11/2021 10:46, Malcolm McLean wrote: > On Friday, 19 November 2021 at 01:22:36 UTC, Siri Cruise wrote: >> In article <sn6jgl$val$1...@dont-email.me>, >> David Brown <david...@hesbynett.no> wrote: >> >>> It is not a matter of a system not having "malloc" and a heap - it is a >>> matter of deciding not to use it. In small systems with limited ram and >> So you cut off your hand and now you want to be told how to >> fashion a hook. Got it. Good luck. >> > David Brown probably didn't take the decision himself not to use malloc. Note that I am not the OP here - I merely work with a similar kind of programming as the OP. > Dynamic memory is often banned, by over-all coding requirements that > are decided upon by senior mangement or customers. > > The question then is what to do when you have a string whose length isn't > known at compile time. > The answer for small-systems embedded programming is to change the question - make sure you /do/ know the length of the string. Or rather, know the maximum length you will have to handle, make sure you /can/ handle that length, and make sure that any external input is limited to that length.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2021-11-19 17:26 +0100 |
| Message-ID | <sn8j86$ejj$1@dont-email.me> |
| In reply to | #163488 |
On 19/11/2021 02:22, Siri Cruise wrote: > In article <sn6jgl$val$1@dont-email.me>, > David Brown <david.brown@hesbynett.no> wrote: > >> It is not a matter of a system not having "malloc" and a heap - it is a >> matter of deciding not to use it. In small systems with limited ram and > > So you cut off your hand and now you want to be told how to > fashion a hook. Got it. Good luck. > Eh, no. You haven't got it at all. Small systems embedded programming is a different world from PC programming - the requirements are different, the hardware is different, the rules are different. We don't write code with error handlers that log problems and send debug data back to the developers - we write code that may have to run for /years/ without a glitch. (I'm not suggesting embedded programmers don't make mistakes - merely that it is common to impose restrictions and coding standards to reduce the risk of errors or their consequences.)
[toc] | [prev] | [next] | [standalone]
Page 2 of 3 — ← Prev page 1 [2] 3 Next page →
Back to top | Article view | comp.lang.c
csiph-web