I've two questiond regarding variable arguments. First, how to count arguments passed ? I see that va_arg macro can be used, but if don't know type of arguments ?
Then, How can a print a % sign with vsnprintf ? Please consider this code:
> I've two questiond regarding variable arguments. > First, how to count arguments passed ?
The <stdarg.h> mechanisms provide no way to do this. You need to deduce the number and type(s) of the variable arguments by examining something else, often something in the fixed arguments. The printf() function[*], for example, uses its format string to figure out what the other arguments are. Or if you know the types of the variable arguments (all `int', say), you might just keep retrieving them until you come to an argument with an agreed-upon special value, like zero or negative one or something that makes no sense as a "real" value.
[*] Since it's a part of the implementation, the printf() function might use some kind of implementation-specific trickery rather than actually using <stdarg.h> -- it might not even be written in C. But it "acts like" a <stdarg.h> function, and its strategy is one you can use yourself.
> I see that va_arg macro can be used, but if don't know type of > arguments ?
You *must* know the type of an argument *before* you try to retrieve it with va_arg(), because you must tell va_arg() what kind of value it is supposed to retrieve.
> // > int main(void) > { > myPrintf("this string should show a %% (percent sign)\n");
> return 0; > }
> on my windows box using PellesC, Gcc, Tcc and Vc++ i get:
> this string should show a (percent sign)
> as you can see % sign is not present, with Lcc I get an empty string.
vsnprintf() finds the "%%" in the format string, and deposits a single '%' in szBuffer. Then you hand szBuffer to printf() *as a format string*. printf() sees the lone '%' sitting there, and thinks "Aha! This is the start of a conversion specifier!" It then tries to figure out what to do with the conversion specifier "% ", and gets confused because there is no percent-space specifier. What happens next is anybody's guess: You've given printf() an invalid format, and printf() can do whatever it feels like.
Suggestion: Change the final printf() to
fputs (szBuffer, stdout);
... which just writes the characters of szBuffer without trying to interpret them as a format string. (In the example code, szBuffer isn't really necessary: You could just use vprintf(), or discard myPrintf() altogether and use printf(). But I assume this is a stripped-down example, and that you intend to do more with szBuffer than you've shown here.)
What happens when you pass this string, containing only a SINGLE percent sign, to printf?
Maybe you should use another function in order to display your output, such as fwrite. Or, if you want to be silly but not do something partiicularly dangerous: printf("%s", szBuffer);
The camel-case and type prefixes are unidiomatic and not useful; if you're going to write C, I recommend you avoid them.
> ... which just writes the characters of szBuffer without > trying to interpret them as a format string. (In the example > code, szBuffer isn't really necessary: You could just use > vprintf(), or discard myPrintf() altogether and use printf(). > But I assume this is a stripped-down example, and that you > intend to do more with szBuffer than you've shown here.)
> The camel-case and type prefixes are unidiomatic and not useful; if > you're going to write C, I recommend you avoid them.
I don't want to make a flame, but I think that "The camel-case and type prefixes are unidiomatic and not useful" for you. Why you recommend to avoid them ?
> Seebs ha scritto: >> The camel-case and type prefixes are unidiomatic and not useful; if >> you're going to write C, I recommend you avoid them. > I don't want to make a flame, but I think that "The camel-case and type > prefixes are unidiomatic and not useful" for you.
"Idiomatic" in this case refers to the broader category of C programming.
> Why you recommend to avoid them ?
Long story.
Idiomatic usage is an important thing, because people have to work on other peoples' code. It is easier for everyone to write correct and efficient C if people follow common conventions. The bulk of existing C has standardized on names like do_some_things() rather than doSomeThings(). That means that, in a large project, there will always be a fair amount of code which has to refer to functions which have lowercase-and-underscores names. If you use camel case for your new functions, you've created a barrier to quick and effective programming; someone who remembers the words "do some things" has to *remember* which way you spelled them, rather than simply writing them using the standard convention. This is of course caught mostly at compile time, but it's a hassle and a distraction.
Type prefixes are in general stupid in a strongly-typed language. They distract the reader from the variable's function to interject with information the reader probably already has readily at hand.
adverbBasically, conjunctionIf nounYou verbFind pronounThis adjectiveReadable, conjunctionMaybe pronounIt verbWorks prepositionFor pronounYou. For most people, it doesn't work.
> Idiomatic usage is an important thing, because people have to work on other > peoples' code. It is easier for everyone to write correct and efficient C > if people follow common conventions. The bulk of existing C has standardized > on names like do_some_things() rather than doSomeThings(). That means that, > in a large project, there will always be a fair amount of code which has > to refer to functions which have lowercase-and-underscores names. If you use > camel case for your new functions, you've created a barrier to quick and > effective programming; someone who remembers the words "do some things" > has to *remember* which way you spelled them, rather than simply writing them > using the standard convention. This is of course caught mostly at compile > time, but it's a hassle and a distraction.
> Type prefixes are in general stupid in a strongly-typed language. They > distract the reader from the variable's function to interject with information > the reader probably already has readily at hand.
> adverbBasically, conjunctionIf nounYou verbFind pronounThis adjectiveReadable, > conjunctionMaybe pronounIt verbWorks prepositionFor pronounYou. For most > people, it doesn't work.
On 9 Nov, 13:40, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-11-09, Alessio <f...@fake.org> wrote: > > Seebs ha scritto: > >> The camel-case and type prefixes are unidiomatic and not useful;
this is of course Mr.Seebach's opionion. It may be better than most opinions on C but it is still an opinion. I can live with camel case. Actually I have to, as source bases I deal with in both C and C++ are CamelCased. For reasons I'm not too sure about camelCase seems much more prevelent in the C++ than the C world. You can reprogram yourself to be equally happy in either.
Type prefixs on the other hand are Pure Evil. Search for Hungarian Notation on the internet.
> >>if you're going to write C, I recommend you avoid them.
unless the rest of project team is using them. Or you're using an API that uses them heavily (eg. Win32). I tend to hide Win32's programming conventions away from the rest of my code as much as possible. And only partly becasue they're ugly?
> > I don't want to make a flame, but I think that "The camel-case and type > > prefixes are unidiomatic and not useful" for you.
> "Idiomatic" in this case refers to the broader category of C programming.
do you have figures?
> > Why you recommend to avoid them ?
> Long story.
> Idiomatic usage is an important thing, because people have to work on other > peoples' code. It is easier for everyone to write correct and efficient C > if people follow common conventions. The bulk of existing C has standardized > on names like do_some_things() rather than doSomeThings().
I've seen a fair amount that doesn't follow your conventions!
> That means that, > in a large project, there will always be a fair amount of code which has > to refer to functions which have lowercase-and-underscores names.
not always...
> If you use > camel case for your new functions, you've created a barrier to quick and > effective programming; someone who remembers the words "do some things" > has to *remember* which way you spelled them, rather than simply writing them > using the standard convention. This is of course caught mostly at compile > time, but it's a hassle and a distraction.
> Type prefixes are in general stupid in a strongly-typed language.
oh agreed. stupid-stupid-stupid might be nearer the mark
> They > distract the reader from the variable's function to interject with information > the reader probably already has readily at hand.
He should if he writes decent code. The variable you need to know the type of should be either local or a parameter (and hence local again) about 95% of the time. Which means it should only be about 20 lines away at most (you do write functions that fit on a screen, yes?). Ok, you may have some static stuff at the head of the file, but *that* isn't far away either.
I know structs mess up this idealised world, but good naming naming conventions and modularisation practices clean this all up. And you do have a decent sourec code browser don't you?
> adverbBasically, conjunctionIf nounYou verbFind pronounThis adjectiveReadable, > conjunctionMaybe pronounIt verbWorks prepositionFor pronounYou. For most > people, it doesn't work.
Consider this URL that discusses a common Hungarian Type in Microsoft's Windows API blogs.msdn.com/oldnewthing/archive/2003/11/25/55850.aspx
**************** What do the letters W and L stand for in WPARAM and LPARAM? Once upon a time, Windows was 16-bit. Each message could carry with it two pieces of data, called WPARAM and LPARAM. The first one was a 16- bit value ("word"), so it was called W. The second one was a 32-bit value ("long"), so it was called L.
You used the W parameter to pass things like handles and integers. You used the L parameter to pass pointers.
When Windows was converted to 32-bit, the WPARAM parameter grew to a 32-bit value as well. So even though the "W" stands for "word", it isn't a word any more. (And in 64-bit Windows, both parameters are 64- bit values!)
It is helpful to understand the origin of the terms. If you look at the design of window messages, you will see that if the message takes a pointer, the pointer is usually passed in the LPARAM, whereas if the message takes a handle or an integer, then it is passed in the WPARAM. (And if a message takes both, the integer goes in the WPARAM and the pointer goes in the LPARAM.)
Once you learn this, it makes remembering the parameters for window messages a little easier. Conversely, if a message breaks this rule, then it sort of makes your brain say, "No, that's not right." *******************
In other words the Hungarian doesn't mean what it says it means.
On 2009-11-09, Nick Keighley <nick_keighley_nos...@hotmail.com> wrote:
> this is of course Mr.Seebach's opionion. It may be better than most > opinions on C but it is still an opinion. I can live with camel case. > Actually I have to, as source bases I deal with in both C and C++ are > CamelCased. For reasons I'm not too sure about camelCase seems much > more prevelent in the C++ than the C world. You can reprogram yourself > to be equally happy in either.
Probably. I'm not convinced that you can actually ever make camelcase as fast as words separated by visual space, but it can certainly be livable. I use it in Java, and use it partially in Ruby (where conventions are a bit more complex; generally, class names are CamelCase, methods aren't).
> Type prefixs on the other hand are Pure Evil. Search for Hungarian > Notation on the internet.
To be fair, there's some case to be made for apps hungarian, which actually CAN make it easier to spot bugs that a compiler can't.
> unless the rest of project team is using them. Or you're using an API > that uses them heavily (eg. Win32). I tend to hide Win32's programming > conventions away from the rest of my code as much as possible. And > only partly becasue they're ugly?
Heh.
But yeah, you make good points -- it can be more important to do things aligned with the rest of the code base.
>> "Idiomatic" in this case refers to the broader category of C programming. > do you have figures?
Not really.
> I've seen a fair amount that doesn't follow your conventions!
Oh, sure. But look at all the naming conventions used in, say, the C standard, the standard library implementations, the kernels...
>> That means that, >> in a large project, there will always be a fair amount of code which has >> to refer to functions which have lowercase-and-underscores names. > not always...
I've yet to see a decently-written C project not use the standard library (unless it was freestanding, and all the kernel code I've seen sticks with lowercase/underscores).
> In other words the Hungarian doesn't mean what it says it means.
Yes.
Had they used names like "value" and "pointer", there would be no confusion and no need for that explanation.
In <hd941t$p...@aioe.org>, Alessio wrote: > Seebs ha scritto:
>> The camel-case and type prefixes are unidiomatic and not useful; if >> you're going to write C, I recommend you avoid them.
> I don't want to make a flame, but I think that "The camel-case and > type prefixes are unidiomatic and not useful" for you. > Why you recommend to avoid them ?
I agree with Seebs's reasoning on type prefixes - or, at least, on primitive type prefixes. But I see no reason to avoid camel case, if that's what floats your boat. (It certainly floats mine.)
-- Richard Heathfield <http://www.cpax.org.uk> Email: -http://www. +rjh@ "Usenet is a strange place" - dmr 29 July 1999 Sig line vacant - apply within
On 9 Nov, 15:18, Seebs <usenet-nos...@seebs.net> wrote:
> On 2009-11-09, Nick Keighley <nick_keighley_nos...@hotmail.com> wrote: > > [...] I can live with camel case. [...] You can reprogram yourself > > to be equally happy in either [camel or non-camel].
> Probably. I'm not convinced that you can actually ever make camelcase > as fast as words separated by visual space,
to read or to write?
[...]
> > Type prefixs on the other hand are Pure Evil. Search for Hungarian > > Notation on the internet.
> To be fair, there's some case to be made for apps hungarian, which actually > CAN make it easier to spot bugs that a compiler can't.
and I use postfixes in C++ for the n-zillion different type of smart pointer.
but that may reflect on my ability to deal with C++s smart pointers. {for the non-C++ those pointers probably all do different things to the object they point at when they go out of scope)
> > unless the rest of project team is using them. Or you're using an API > > that uses them heavily (eg. Win32). I tend to hide Win32's programming > > conventions away from the rest of my code as much as possible. And > > only partly becasue they're ugly?
> Heh.
> But yeah, you make good points -- it can be more important to do things > aligned with the rest of the code base.
> >> "Idiomatic" in this case refers to the broader category of C programming.
> > do you have figures?
> Not really.
people don't usually so its kind of mean to ask. :-)
> > I've seen a fair amount that doesn't follow your conventions!
> Oh, sure. But look at all the naming conventions used in, say, the C > standard, the standard library implementations, the kernels...
well if you must confine yourself to such a narrow domain.
> >> That means that, > >> in a large project, there will always be a fair amount of code which has > >> to refer to functions which have lowercase-and-underscores names. > > > not always...
> I've yet to see a decently-written C project not use the standard library > (unless it was freestanding, and all the kernel code I've seen sticks > with lowercase/underscores).
I was going to argue a great deal of the code doesn't acll the standard library. But once strcpy() aand so on considered you probably can't go many pages without hitting something standard. I don't actually like camel case I just have to use it.
> > In other words the Hungarian doesn't mean what it says it means.
> Yes.
> Had they used names like "value" and "pointer", there would be no confusion > and no need for that explanation.
Seebs <usenet-nos...@seebs.net> writes: > On 2009-11-09, Alessio <f...@fake.org> wrote: >> Seebs ha scritto: >>> The camel-case and type prefixes are unidiomatic and not useful; if >>> you're going to write C, I recommend you avoid them.
>> I don't want to make a flame, but I think that "The camel-case and type >> prefixes are unidiomatic and not useful" for you.
> "Idiomatic" in this case refers to the broader category of C programming.
>> Why you recommend to avoid them ?
> Long story.
> Idiomatic usage is an important thing, because people have to work on other > peoples' code. It is easier for everyone to write correct and efficient C > if people follow common conventions. The bulk of existing C has standardized > on names like do_some_things() rather than doSomeThings(). That means that, > in a large project, there will always be a fair amount of code which has > to refer to functions which have lowercase-and-underscores names. If you use > camel case for your new functions, you've created a barrier to quick and > effective programming; someone who remembers the words "do some things" > has to *remember* which way you spelled them, rather than simply writing them > using the standard convention. This is of course caught mostly at compile > time, but it's a hassle and a distraction.
> Type prefixes are in general stupid in a strongly-typed language.
Erm, no need to head off-topic - you're posting to comp.lang.c, remember?!
> They > distract the reader from the variable's function to interject with information > the reader probably already has readily at hand.
So we ought to strip the annoying 'f' from open(), write(), flush(), and printf()? And as for those new-fangled 'mb' & 'wc' functions - be gone!
Great. Now we need a new language, you just broke the old one ;-p
Phil -- Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
On 2009-11-09, Phil Carmody <thefatphil_demun...@yahoo.co.uk> wrote:
>> They >> distract the reader from the variable's function to interject with information >> the reader probably already has readily at hand. > So we ought to strip the annoying 'f' from open(), write(), flush(), and > printf()?
I'd say probably not. Prefixes on functions to tell you what they operate on make some sense, because the function is not declared right here. Prefixes on variables declared within a function or in its parameter list are sort of pointless, because the variable is right there to look at.
Thus, "strchr()" not "chr()" (after all, what if you wanted to find a character in something other than a string?), but "s", not "strArgumentString1".
Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes: > Seebs <usenet-nos...@seebs.net> writes: [...] >> They distract the reader from the variable's function to interject >> with information the reader probably already has readily at hand.
> So we ought to strip the annoying 'f' from open(), write(), flush(), and > printf()? And as for those new-fangled 'mb' & 'wc' functions - be gone!
> Great. Now we need a new language, you just broke the old one ;-p
The C standard library is not, never has been, and almost certainly never will be a model of internal consistency.
Apart from Seebs's remarks about the distinction between functions and (local) variables, functions need to have distinct names, and there are often multiple versions of a given function that operate on different types. The 'f' on sqrtf() is more for the compiler's (and linker's) benefit than for the reader's benefit.
(Yes, I'm responding seriously to what was probably at least partly written in jest, but there are serious points to be made.)
-- Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"
Keith Thompson <ks...@mib.org> writes: > Phil Carmody <thefatphil_demun...@yahoo.co.uk> writes: >> Seebs <usenet-nos...@seebs.net> writes: > [...] >>> They distract the reader from the variable's function to interject >>> with information the reader probably already has readily at hand.
>> So we ought to strip the annoying 'f' from open(), write(), flush(), and >> printf()? And as for those new-fangled 'mb' & 'wc' functions - be gone!
>> Great. Now we need a new language, you just broke the old one ;-p
> The C standard library is not, never has been, and almost certainly > never will be a model of internal consistency.
> Apart from Seebs's remarks about the distinction between functions > and (local) variables, functions need to have distinct names, and > there are often multiple versions of a given function that operate > on different types. The 'f' on sqrtf() is more for the compiler's > (and linker's) benefit than for the reader's benefit.
> (Yes, I'm responding seriously to what was probably at least partly > written in jest, but there are serious points to be made.)
Indeed. I don't stick my tongue out to Peter unless I'm joshing.
The switching of functions for variables was indeed not very subtle sleight of hand too, but as I'd just seen "do_some_things() rather than doSomeThings()", I thought I could conflate the two objections.
And I would have got away with it if it wasn't for you pesky meddling regs ;-p
Phil -- Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
> On 9 Nov, 15:18, Seebs <usenet-nos...@seebs.net> wrote: > > On 2009-11-09, Nick Keighley <nick_keighley_nos...@hotmail.com> wrote: > > > I can live with camel case. You can reprogram yourself > > > to be equally happy in either camel or non-camel.
> > Probably. I'm not convinced that you can actually ever make camelcase > > as fast as words separated by visual space
"ALGOL 60 was a language so far ahead of its time that it was not only an improvement on its predecessors but also on nearly all its successors". --C.A.R. Hoare