Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #147568
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: memcpy not memcpying? |
| Date | 2019-11-04 11:00 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <qposrb$2sq$1@dont-email.me> (permalink) |
| References | (15 earlier) <1BAvF.13970$mB7.12243@fx32.am4> <qpn0a2$dn3$1@dont-email.me> <%%DvF.115593$Yl3.480@fx24.am4> <qpnj12$17q$1@dont-email.me> <BoJvF.123253$m0L.2016@fx15.am4> |
On 04/11/2019 00:28, Bart wrote:
> On 03/11/2019 22:06, David Brown wrote:
>> On 03/11/2019 18:20, Bart wrote:
>
>>> (1) A numeric type T exported from a library's header. You want to print
>>> it, but now you have to delve into the header to find out what type
>>> it is, to work out what format it needs.
>>>
>>
>> I don't use types when I don't know their relevant characteristics.
>
> You do some includes such as:
>
> #include <windows.h>
> #include <gtk.h>
I don't. C is a terrible choice of language for gui programming (on
Windows or Linux). The main reason MS never bothered to support C99 in
their C compiler and libraries (until very recently) is that few sane
developers have used C for gui application programming since long before
C99 was established.
But we will leave that aside for now, and assume my C code has include
files with thousands of types.
>
> and you're importing possibly 1000s of types. You're not going to be
> able to keep track of them. And every so often, you will need to
> printout values of those types, or the results of calculations with
> those types.
What I said, is that I don't use types when I don't know their
/relevant/ characteristics.
Re-read that. Maybe re-read it again.
For the majority of types, the relevant characteristics for me, as a
user of the include files, is nothing more than that they are
identifiers I can't use in my own code. A file that includes headers
like "windows.h" is likely to use perhaps 0.1 % of the functions, types,
constants, macros, etc., declared in those headers.
For most of the types that would be used, the relevant characteristics
might be no more than "I get values of this type like this, I send them
out like that". Gui-related types might include handles, widgits,
colours, etc. You don't care about the details. You often don't care
if it is a handle, or a struct, or a pointer to a struct. You don't
care if the underlying type is big or small - you only care that you can
use it in the way documented by the library.
Then you might be left with a few - a very few - numeric types. Things
like "DWORD" or "int32" - hangovers from the past, when using libraries
that were developed before C99 was standardised. You know what size
these types are, they don't change, and if you don't know, you don't use
them.
>
>> Have you ever heard the phrase "Don't repeat yourself", with the
>> acronym DRY? You write code to output the type once, and use it
>> wherever it is needed. If T changes, you change the one function.
>
> Huh? You write this
>
> int nsymbols;
>
> In 100 places in the program, you might have code like this:
>
> printf("Symbol %d out of %d",i, nsymbols);
>
> Then one day, you decide to change it to:
>
> long long int nsymbols;
>
> Now all those %d's that refer to nsymbols in a format string need to be
> changed. Plus possibly variables such as that 'i' above, and /its/ format.
No, you don't write that.
You plan your program. Is it realistic to think that the type of
"nsymbols" would change - that 2 G symbols will not be enough? If that
is the case, you write:
typedef int symbolcount_t;
symbolcount_t nsymbols;
#define PRIsymbolcount d
void debug_print_symbolcounts(symbolcount__t i) {
printf("Symbol %" PRIsymbolcount " out of %" PRIsymbolcount,
i, nsymbols);
}
Or maybe, if you don't like printf format macros (and lets be honest, no
one does - even if it is the least bad solution, it is still ugly), you
write:
typedef int symbolcount_t;
symbolcount_t nsymbols;
void print_symbolcounts(symbolcount_t i) {
_Static_assert(sizeof(symbolcount_t) == sizeof(int),
"Fix this function if symbolcount_t changes");
printf("%d", i);
}
You abstract things that are likely to change. That lets you make
changes to the program later. It means that you can change your type,
or perhaps the format of the output. (What help is "%?" if you later
decide the numbers should have thousands separators in them?)
Of course you can't abstract everything, and you can't predict all
changes of future versions. So sometimes you will be faced with doing a
search and replace on the /ten/ occurrences of the print string in the code.
And sometimes you are faced with firing the programmer who wrote the
same print string /hundreds/ of times in the code.
>
> If nsymbols is defined in some imported header, you might not even be
> aware of any change.
I am aware of such changes.
Perhaps there are weaknesses in your development practices that let such
problems slip through unnoticed. I am sure others could find plenty of
flaws or "improvement areas" in my own development practices, but this
is not one of them.
There are three key methods here.
1) I don't use different versions of headers without checking what
changes might be relevant. API's of libraries, OS's, etc., do not
change in this way, so the issue is only realistic for major updates in
a library, or for code under development. And you don't use different
versions of code being developed without understanding the changes.
2) If there is something that is likely to change, or if I am making
assumptions that could be wrong in the future or in different
circumstances, I use static assertions or appropriate conditional
compilation. When something changes, the code is either automatically
adapted, or there is a compile-time error.
3) I use static error checking to catch problems, with heavy use of
warnings appropriate to the code - and I pay attention to any warnings.
(This is not C specific - I do it with any programming, adjusted for the
features and tools of the language.)
>
>> Of course, that kind of coding might be unfamiliar to someone who
>> rejects majors, inline functions, typedefs, and other features aimed
>> at such abstractions in coding.
>
> Yet the entire C language rejects type abstraction when it comes to
> printf formats!
>
>> #if cond
>> int x;
>> #define PRIx %d
>> #elif
>> double x;
>> #define PRIx %f
>> #endif
>
> Yuck.
>
> However nobody actually does it. (Look at one of those 50-line #if/#elif
> chains of conditionals that end up defining some vital type. They NEVER
> also define a corresponding print format.)
>
It is a way to handle the situation. It's a bit ugly - no disagreement
there. But you have the ugliness hidden away.
There are other methods, of course. I mentioned one earlier in this
post. Another idea is to use _Generic macros (which are ugly to define,
but easy to use).
printf is flexible, but it has its limitations. There are lots of
things it can't do. If it doesn't suit your needs, solve the problem in
a different way - printf calls are not the only way to do output in C.
Programming is about finding solutions to problems, not about assuming
there is only one solution and then trying to invent problems it can't
solve.
> And this definition could be inside someone else's header that you are
> importing.
>
> All you want to do is quickly print the value of .st_rdev of a 'stat'
> struct, of which one of half a dozen variations could be conditionally
> defined. Good luck finding a print format defined too! It's just not
> going to happen.
>
> Your best bet might be actually printing as float, and converting to
> float, provided the magnitude is under 2**52, but it's a hell of thing
> to have to do, especially if you'd prefer it as hex!
>
> printf("s.st_rdev = %f\n", (double)s.st_rdev);
>
> compared with:
>
> printf("%=?\n", s.strdev);
>
>
>> As I say, I don't write code using types that I don't know. So your
>> complaint is meaningless.
>
> No it isn't. It's perfectly legitimate. You're debugging someone's
> 100,000-line project with a thousand types, and thousands of variables
> and functions of different types, and you need to print out the value of
> the index here:
>
> a[f(x)+y]=0;
>
> as printf("f(x)+y = %...\n", f(x)+y); but what goes in the "..."?
printf("f(x)+y = %zu\n", (size_t) (f(x)+y));
I know enough about the types to know this is valid.
Oh, and I know how to use a debugger. It's often a handy tool when
debugging.
> You
> have to assume it is something compatible with int or size_t (you don't
> even know what type array indices are supposed to be!), but you can't
> tell just from that fragment.
>
> All your suggestions are workarounds and mitigations for a fundamental
> short-coming.
No one has ever claimed that "printf" does everything. What you call
"workarounds and mitigations", other people call "finding solutions" or
"programming".
I think you are so used to living in your own little world with your own
little programming languages, that you have lost your understanding of
how /real/ programming is done. When you have a situation that you
can't handle simply and immediately in your own language, your answer is
to change the language. For other people, the answer is to /use/ the
language they have.
>
>>>
>>> The "%?" suggestion works with all of these when the type is numeric,
>>> and in many cases also when the type is a pointer or string.
>>
>> It is an idea that can work in a more interpreted style of language.
>> It is not a bad idea, and could be very convenient.
>
> It is. I can write for my above example:
>
> printf("f(x)+y= %?\n",f(x)+y);
>
> and not know nor care what the relevant types are. I've just tried it
> and it works with int, long long int, double or even char*. It's less
> work, more productive and less error prone.
Tell me how you print the value in binary. Tell me how you choose to
add thousands separators. Tell me how this works if f(x) returns a
string and y is a character, or where the types are matrices.
C printf can't solve these. Neither can your language, I believe.
Other languages - such as Python and C++ - can handle them neatly (once
you have written the appropriate support code for your types).
Different languages are useful for different purposes.
Your "%?" is a step up in convenience for printf. But it is only a
small step up, and in C the cost would be far too high. If you like it
for your own language, that's up to you - but it is not something that C
is missing in any way.
>
>> If "%?" is something that works for you in your languages, great.
>> That does not mean it is something that other people would like in C.
>
> I think they would. Ben said in another post that Haskell has C-like
> formats, but also "v" that works for any variable. That is the
> equivalent of my "?" (which I can change to "v" if that has no existing
> meaning).
Haskell is not C. There are vast amounts of cool features in Haskell
that C does not have - and equally, vast amounts of things that are
simple to do in C, but much harder to handle in a language like Haskell.
>
> But I can't imagine when someone writing Haskell would want to bother
> with anything other than "v".
You base this on your vast experience with Haskell programming?
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 08:42 -0400
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 08:49 -0400
Re: memcpy not memcpying? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-01 09:24 -0400
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 09:46 -0400
Re: memcpy not memcpying? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-01 09:49 -0400
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-01 10:19 -0700
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-01 21:14 +0100
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 17:16 -0400
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-01 22:42 +0000
Re: memcpy not memcpying? Richard Damon <Richard@Damon-Family.org> - 2019-11-01 21:10 -0400
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 11:36 +0000
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-02 02:15 -0700
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-02 13:04 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 13:43 +0000
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-02 17:24 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 17:00 +0000
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-02 13:06 -0700
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 21:05 +0000
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 22:40 +0000
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-02 15:59 -0700
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-02 23:47 +0000
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-02 18:22 -0700
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 13:27 +0000
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-03 17:46 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 17:20 +0000
Re: memcpy not memcpying? Manfred <noname@add.invalid> - 2019-11-03 19:44 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 19:36 +0000
Re: memcpy not memcpying? Manfred <noname@add.invalid> - 2019-11-03 22:57 +0100
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-03 22:39 +0000
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-03 23:06 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 23:28 +0000
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-04 11:00 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-04 11:14 +0000
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-04 11:22 +0000
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-04 13:10 +0100
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-04 10:03 -0800
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-04 19:36 +0000
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-05 10:04 -0800
Re: memcpy not memcpying? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-04 20:58 -0800
Re: memcpy not memcpying? Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-11-04 22:01 -0800
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-04 12:56 +0100
Re: memcpy not memcpying? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-04 09:50 -0500
Re: memcpy not memcpying? scott@slp53.sl.home (Scott Lurndal) - 2019-11-04 20:26 +0000
Re: memcpy not memcpying? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-11-04 04:34 -0800
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-04 13:05 +0000
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-04 14:09 +0000
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-04 15:11 +0000
Re: memcpy not memcpying? Melzzzzz <Melzzzzz@zzzzz.com> - 2019-11-04 15:15 +0000
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-04 15:43 +0000
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 20:20 +0000
Re: memcpy not memcpying? Ian Collins <ian-news@hotmail.com> - 2019-11-03 14:37 +1300
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 11:01 +0000
Re: memcpy not memcpying? Öö Tiib <ootiib@hot.ee> - 2019-11-03 04:03 -0800
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 12:52 +0000
Re: memcpy not memcpying? Öö Tiib <ootiib@hot.ee> - 2019-11-03 23:34 -0800
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-04 09:36 +0000
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-04 16:20 +0000
Re: memcpy not memcpying? Ian Collins <ian-news@hotmail.com> - 2019-11-04 07:46 +1300
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-03 12:26 -0800
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-03 17:31 +0100
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-03 17:05 +0000
Re: memcpy not memcpying? already5chosen@yahoo.com - 2019-11-03 09:14 -0800
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-03 12:32 -0800
Re: memcpy not memcpying? already5chosen@yahoo.com - 2019-11-03 14:59 -0800
Re: memcpy not memcpying? already5chosen@yahoo.com - 2019-11-03 15:19 -0800
Re: memcpy not memcpying? already5chosen@yahoo.com - 2019-11-03 17:00 -0800
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-02 11:16 -0400
Re: memcpy not memcpying? David Brown <david.brown@hesbynett.no> - 2019-11-02 17:26 +0100
Re: memcpy not memcpying? Barry Schwarz <schwarzb@delq.com> - 2019-11-01 06:39 -0700
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 09:56 -0400
Re: memcpy not memcpying? Barry Schwarz <schwarzb@delq.com> - 2019-11-01 12:39 -0700
Re: memcpy not memcpying? guinness.tony@gmail.com - 2019-11-01 06:49 -0700
Re: memcpy not memcpying? jak <nospam@please.ty> - 2019-11-01 20:40 +0100
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 14:26 +0100
Re: memcpy not memcpying? Keith Thompson <kst-u@mib.org> - 2019-11-01 10:22 -0700
Re: memcpy not memcpying? Bart <bc@freeuk.com> - 2019-11-01 19:44 +0000
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 21:31 +0100
Re: memcpy not memcpying? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-01 09:39 -0400
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 14:42 +0100
Re: memcpy not memcpying? James Kuyper <jameskuyper@alumni.caltech.edu> - 2019-11-01 09:48 -0400
Re: memcpy not memcpying? Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2019-11-01 06:47 -0700
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 14:58 +0100
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 10:22 -0400
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 18:38 +0100
Re: memcpy not memcpying? scott@slp53.sl.home (Scott Lurndal) - 2019-11-01 17:54 +0000
Re: memcpy not memcpying? Autist <autist69@gmail.com> - 2019-11-01 20:24 +0100
Re: memcpy not memcpying? DFS <nospam@dfs.com> - 2019-11-01 15:24 -0400
Re: memcpy not memcpying? Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-11-01 23:19 +0000
csiph-web