473,432 Members | 1,685 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,432 software developers and data experts.

C99 IDE for windows

I'm looking for a freeware c99 compiler for windows. I had intended to use
MS's Visual C++ Express and use its C capability. In the past with my MS
products, I've simply needed to make .c the filetype to invoke the C
compiler. Here's a link

http://www.microsoft.com/express/download/#webInstall

The download is 2.6 megs, which is near a reasonable size for a compiler,
but then setup.exe wants to download 87 megs of dot net framework hoggs
that I don't want on my machine.

In the past I've gone with Bloodshed, but I find myself unable to get the
shell to stay open so I can see some output.

The development environment for gcc is austere.

Anyone have another suggestion?
--
Women have simple tastes. They get pleasure out of the conversation of
children in arms and men in love.
H. L. Mencken
Jul 19 '08
173 13748
santosh wrote:
Richard Heathfield wrote:
.... snip ...
>
>open a shell, find the program, run the program from the shell.

That's the ideal. But assuming that 'pereges' cannot do that
(since if he could, he obviously wouldn't be misusing getch like
this), getchar provides the behaviour he needs (block just before
return from main) without rendering the code nonportable.
He can. He just hasn't learned how.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 6 '08 #101
CBFalconer wrote:
santosh wrote:
>Richard Heathfield wrote:
... snip ...
>>
>>open a shell, find the program, run the program from the shell.

That's the ideal. But assuming that 'pereges' cannot do that
(since if he could, he obviously wouldn't be misusing getch like
this), getchar provides the behaviour he needs (block just before
return from main) without rendering the code nonportable.

He can. He just hasn't learned how.
Perhaps, but teaching him to open a shell is off-topic for this group,
as is getch(), hence the advise to use getchar().

Aug 6 '08 #102
CBFalconer said:
Nick Keighley wrote:
>Richard Heathfield <r...@see.sig.invalidwrote:

[RCH doesn't seem to like snprintf()]
[I must admit its lack of portability puts me off]

What's non-portable?
Programs that rely on the existence and semantics of snprintf.
It is specified in the C99 standard.
Non sequitur.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 6 '08 #103
In article <g7**********@registered.motzarella.org>,
santosh <sa*********@gmail.comwrote:
>CBFalconer wrote:
>santosh wrote:
>>Richard Heathfield wrote:
... snip ...
>>>
open a shell, find the program, run the program from the shell.

That's the ideal. But assuming that 'pereges' cannot do that
(since if he could, he obviously wouldn't be misusing getch like
this), getchar provides the behaviour he needs (block just before
return from main) without rendering the code nonportable.

He can. He just hasn't learned how.

Perhaps, but teaching him to open a shell is off-topic for this group,
as is getch(), hence the advise to use getchar().
There you have it gentlemen. What more evidence do you need?

(For those of you slow on the uptake: The "it" is proof that the regs
and wannabees [santosh] would far, far rather give totally worthless and
incomprehensible [to newbies] advice, than give a useful "off-topic"
answer.)

Aug 6 '08 #104
Richard Heathfield <rj*@see.sig.invalidwrites:
santosh said:
[...]
>Of course the 'p' specifier throws an additional spanner into the works.

I think it throws a spanner into snprintf's works, too - I could be wrong,
but is there any *obligation* on implementations to choose the same
textual representation for a pointer on every invocation? If not, then
snprintf's "let me tell you how big a buffer you would have needed *this*
time" doesn't really mean a lot where %p is concerned.
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.

With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer. Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.

With sprintf, you can make a reasonable guess, but the consequence of
guessing wrong is undefined behavior.

And even for integer and floating-point arguments, where you can (I
think) portably determine the maximum length, getting it right is
still a tedious and error-prone process.

--
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"
Aug 6 '08 #105
Richard Heathfield <rj*@see.sig.invalidwrites:
santosh said:
>pereges wrote:

<snip>
>>In blood shed, using a getch() statement just before the return 0
statement in main function has worked for me. The shell stays open
(unless you enter some character) and you can see the output.

I think its not considered standard C but if seeing the output is the
only aim then nothing wrong with it I guess.

What's wrong with:

getchar();

What's wrong with:

open a shell, find the program, run the program from the shell.
Or find an option in the IDE that tells it not to close the output
window when the program finishes.

--
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"
Aug 6 '08 #106
santosh <sa*********@gmail.comwrites:
Richard Heathfield wrote:
[...]
>Implementations are perfectly free to
document this choice along lines such as "if the -foo switch is set,
UINT_MAX is 131071, otherwise if -bar is set it's 262143, otherwise
it's 37778931862957161709567".

Wouldn't that actually make them three different implementations, in
effect?
Yes, I believe it would. And writing code to allow for any of those
possibilities is just an example of writing code that's portable to
several implementations.

[...]
But the forms of behaviour must be derivable, or otherwise, it would be
undefined.

So, in view of all this, how is one, as an implementor, to derive the
valid forms of behaviour for the implementation defined output for
the 'p' type specifier in printf? The final choice of the
implementation must be one from a set of 2 to N choices that the
Standard must specify literally or implicitly through it's constraints.
But what constraints can one apply to this case? Any ideas?
C99 7.19.6.2p8:

p The argument shall be a pointer to void. The value of the
pointer is converted to a sequence of printing characters, in
an implementation-defined manner.

So the constraint (not a "Constraint", just a plain old constraint) is
that the result must be a sequence of printing characters.

--
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"
Aug 6 '08 #107
Keith Thompson said:

<snip>
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.
Right.
With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer.
Right.
Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.
Right.
With sprintf, you can make a reasonable guess, but the consequence of
guessing wrong is undefined behavior.
If we're allowed a preliminary length-determining operation (as in your
first call to snprintf), we can use fprintf to write the pointer's text
representation to a temporary file and, at the same time, find out how
long it is; then we can seek back in the file and read from the file into
the string. Easy.
And even for integer and floating-point arguments, where you can (I
think) portably determine the maximum length, getting it right is
still a tedious and error-prone process.
No, not really. We can say "our application is required to support values
in such-and-such a range, so we'll do that, and perhaps provide a bit of
leeway, and then we'll treat anything that won't fit as an exception to be
reported upon and investigated, but in the meantime we're not going to
accept it as part of our string". We have to do this anyway for other
reasons - for example, if we're dealing with ages of living humans we
don't bother supporting ages of, say, 1000+ - so we range-check it and use
%3d and don't care that our super-amazing-ints can hold 85-digit values
because we still only spec three bytes for the text rep of the age value.
(Yes, I know we need one more for the null character.) If we come across
an age of 1000+, we flag that record as needing attention and we move on
to other things /without/ printing it.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 6 '08 #108
santosh said:

<snip>
Hmm, so for this instance of unspecified behaviour the Standard omits
specifying directly one or more possibilities, and thus *all*
possibilities are implicitly specified, subject only to the constraints
and the syntax of the language. Okay, I think I get it.
Right.

<snip>
So, in effect, an implementation must chose one particular value from a
set of values for UINT_MAX implicitly allowed by the Standard, by not
specifying one or more particular values, but simply a limit and some
related rules.
Right.
>Implementations are perfectly free to
document this choice along lines such as "if the -foo switch is set,
UINT_MAX is 131071, otherwise if -bar is set it's 262143, otherwise
it's 37778931862957161709567".

Wouldn't that actually make them three different implementations, in
effect?
In this case, yes, because the thingy has to be an integer constant. But
don't deduce a general rule from this.
>For iscntrl, implementations are free
to specify just about anything they like as a control character, and I
can find no prohibition on this choice being made dynamically, as long
as the rules are clearly specified (i.e. the implementation documents
how the choice is made).

But these rules themselves should remain constant for any single
invocation of the implementation. Is that right.
Yes. Of course, the rules might allow for considerable (but fully
documented) runtime freedom.
So by that reasoning, if I'm correct (and I don't think I am),
implementations can specify a "dynamic rule" or a set of such rules
whereby the value of the constants in limit.h can vary from one
instance of time to another, even within a single invocation of the
implementation (by which I'm including both the translation and
execution environment, and the execution of the program image too)? Is
this logic sound?
Yes, provided that other constraints (small c) don't interfere (as with
UINT_MAX, which has to be a /constant/ throughout the translation and
execution of the program).

<snip>
Okay. So unspecified behaviour essentially means that the Standard
either specifies N possibilities (where N >= 2), or specifies one or
more constraints (must they only be constraints?),
Small c. Just plain vanilla Chambers dictionary constraints, not ISO/IEC
9899 "oh look, we just defined a word to have a new meaning" Constraints
with a big C.
which when applied
to the construct yield N possible behaviours?
Well, you can have ONE rule that gives MANY possible behaviours. But
speaking a little more broadly, yes, you're basically right.

<snip>
But the forms of behaviour must be derivable, or otherwise, it would be
undefined.
Yes. For example, if the implementation documents that it precedes the nth
instance of %p output with Fib(n) spaces, well, you could actually derive
that, couldn't you? (It might take a little work, but it is possible.)
>
So, in view of all this, how is one, as an implementor, to derive the
valid forms of behaviour for the implementation defined output for
the 'p' type specifier in printf?
That's easy - the implementor can simply say, "I do %p like this", and
'this' can be as simple or as complicated as he wants, as long as he's
consistent.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 6 '08 #109
Richard Heathfield <rj*@see.sig.invalidwrites:
Keith Thompson said:
[...]
>With sprintf, you can make a reasonable guess, but the consequence of
guessing wrong is undefined behavior.

If we're allowed a preliminary length-determining operation (as in your
first call to snprintf), we can use fprintf to write the pointer's text
representation to a temporary file and, at the same time, find out how
long it is; then we can seek back in the file and read from the file into
the string. Easy.
Um, sure. It seems unlikely that anyone would do that in real-world
code. Creating a new file is likely to have have substantially
greater overhead than whatever in-memory formatting is done for "%p".

If I don't want to assume the existence of snprintf, I'm likely to
declare a buffer that I can be *reasonably* sure is bigger than any
string I'm going to write to it. I might even compare the result of
sprintf to the size of the buffer; yes, I've already invoked undefined
behavior at that point, but it can't hurt and it's *likely* to give me
a meaningful answer. The memory I've just clobbered past the end of
the buffer *probably* won't interfere with the comparison -- unless it
crashes the program immediately.

Using fprintf to write to a temporary file is one of those solutions
that's 100% portable rather than 99.9% portable, but at the cost of
substantial performance penalties. It reminds me of using a busy loop
with a call to time() to simulate a system-specific sleep() function.
>And even for integer and floating-point arguments, where you can (I
think) portably determine the maximum length, getting it right is
still a tedious and error-prone process.

No, not really. We can say "our application is required to support values
in such-and-such a range, so we'll do that, and perhaps provide a bit of
leeway, and then we'll treat anything that won't fit as an exception to be
reported upon and investigated, but in the meantime we're not going to
accept it as part of our string". We have to do this anyway for other
reasons - for example, if we're dealing with ages of living humans we
don't bother supporting ages of, say, 1000+ - so we range-check it and use
%3d and don't care that our super-amazing-ints can hold 85-digit values
because we still only spec three bytes for the text rep of the age value.
(Yes, I know we need one more for the null character.) If we come across
an age of 1000+, we flag that record as needing attention and we move on
to other things /without/ printing it.
Unless the routine in question is fairly low-level, and is just
printing a value of type int, or long, or double, without knowing what
it means. Then you have to *manually* calculate the maximum length of
the result of each conversion, and add them all up -- and get a buffer
overflow anyway because you forgot to carry the 1 and there's no way
the compiler can catch your mistake. It's like Fortran's old
Hollerith constants, only worse.

That's why snprintf was invented. And if you can't depend on your
implementation providing it, you can always grab an open source
version, change the name, and include it in your code.

--
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"
Aug 6 '08 #110
Keith Thompson wrote:
>
.... snip ...
>
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.

With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer. Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.
I disagree, and published the following elsethread:

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice. The first time
replace the string with NULL and the size with 0. The returned
value will specify how many chars are needed. Add 1 (for the '\0'
mark), find or make a buffer with that space, and do the second
call.

If the items are likely to change between calls, copy them to
appropriate locations first. Then check and print from those.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 6 '08 #111
>Richard Heathfield <rj*@see.sig.invalidwrites:
>If we're allowed a preliminary length-determining operation (as in your
first call to snprintf), we can use fprintf to write the pointer's text
representation to a temporary file and, at the same time, find out how
long it is; then we can seek back in the file and read from the file into
the string. Easy.
In article <ln************@nuthaus.mib.org>
Keith Thompson <ks***@mib.orgwrote:
>Um, sure. It seems unlikely that anyone would do that in real-world
code.
I have done it.
>Creating a new file is likely to have have substantially
greater overhead than whatever in-memory formatting is done for "%p".
I created the file only once, opening it in "w+" mode and doing
rewind() each time I re-used it.

The inner part of the engine ended up looking something like this:

static FILE *temp_file;

... some code goes here to create the temp file ...

char *mallocating_vsprintf(size_t maxlen, const char *fmt, va_list ap) {
int len;
size_t r;
char *result;

if (temp_file == NULL)
init_temp_file(); /* note, not allowed to fail */

rewind(temp_file);
len = vfprintf(temp_file, fmt, ap);
if (len < 0 || fflush(temp_file))
... handle error ...

if (maxlen != 0 && len maxlen)
len = maxlen;

result = malloc(len + 1);
if (result == NULL)
... handle error ...

rewind(temp_file);
r = fread(result, 1, len, temp_file);
if (r != len)
... handle error ...

result[len] = '\0'; /* terminate string */
return result;
}

(I forget whether the maxlen parameter was always required; this
version accepts 0 to mean "as big as it came out to be". I also
forget how I handled the various error cases. It is possible I
was implementing snprintf() itself, rather than a malloc()-ing
vsnprintf; in this case the malloc step is unnecessary.)
>Using fprintf to write to a temporary file is one of those solutions
that's 100% portable rather than 99.9% portable, but at the cost of
substantial performance penalties.
It turned out not to be a problem with what I was doing (which was
a version of Gosling Emacs). The limited-length printing was used
mostly for interactive operation, where "performace" was mainly
limited by the user typing, rather than the computer computing.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: gmail (figure it out) http://web.torek.net/torek/index.html
Aug 6 '08 #112
On Aug 6, 12:31 pm, Richard Heathfield <rj*@see.sig.invalidwrote:
Keith Thompson said:

<snip>
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.

Right.
With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer.

Right.
Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.

Right.
With sprintf, you can make a reasonable guess, but the consequence of
guessing wrong is undefined behavior.

If we're allowed a preliminary length-determining operation (as in your
first call to snprintf), we can use fprintf to write the pointer's text
representation to a temporary file and, at the same time, find out how
long it is; then we can seek back in the file and read from the file into
the string. Easy.
And even for integer and floating-point arguments, where you can (I
think) portably determine the maximum length, getting it right is
still a tedious and error-prone process.

No, not really. We can say "our application is required to support values
in such-and-such a range, so we'll do that, and perhaps provide a bit of
leeway, and then we'll treat anything that won't fit as an exception to be
reported upon and investigated, but in the meantime we're not going to
accept it as part of our string". We have to do this anyway for other
reasons - for example, if we're dealing with ages of living humans we
don't bother supporting ages of, say, 1000+ - so we range-check it and use
%3d and don't care that our super-amazing-ints can hold 85-digit values
because we still only spec three bytes for the text rep of the age value.
(Yes, I know we need one more for the null character.) If we come across
an age of 1000+, we flag that record as needing attention and we move on
to other things /without/ printing it.
Seems like it's a bit hard to reason with Richard, so let's move onto
practice a bit...

Coincidentally, just a while ago I found myself using snprintf() in a
program to turn a number into a string:

....
size_t serviceLen = 5;
char *service = malloc(sizeof(char) * serviceLen);
if (service == NULL)
return FTT_ERROR_OUT_OF_MEMORY;

while (snprintf(service, serviceLen, "%d", port) >= serviceLen) {
serviceLen += 5;
char *new = realloc(service, sizeof(char) * serviceLen);
if (new == NULL) {
free(service);
return FTT_ERROR_OUT_OF_MEMORY;
}

service = new;
}
....

(Sorry for the undefined identifiers--it's part of a larger codebase.
Oh, 'port' is an integer, BTW). Would you be so kind as to modify this
code snippet so that it doesn't use snprintf() or vsnprintf()? And
let's see how "easy" it is to do it by writing to a temporary file or
checking maximum integer widths.

Sebastian

Aug 6 '08 #113
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
... snip ...
>>
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.

With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer. Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.

I disagree, and published the following elsethread:

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice. The first time
replace the string with NULL and the size with 0. The returned
value will specify how many chars are needed. Add 1 (for the '\0'
mark), find or make a buffer with that space, and do the second
call.

If the items are likely to change between calls, copy them to
appropriate locations first. Then check and print from those.
Right, but I'm not sure what you're disagreeing with.

You're suggesting a slightly different approach than I am, but I think
both are valid. Your approach always requires calling snprintf twice,
once to determine the required length, and again to store the actual
string. My approach guesstimates the required size. If the guess is
right, you only need one call; if you guessed wrong, call snprintf
again with a bigger buffer.

The qualification "Even if you're given an even bigger string on the
second attempt" was intended to cover the unlikely case where "%p"
with the same argument gives a longer string on the second call than
on the first. Even in that bizarre circumstance, snprintf still
avoids a buffer overflow.

--
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"
Aug 6 '08 #114
Keith Thompson wrote:
CBFalconer <cb********@yahoo.comwrites:
>Keith Thompson wrote:

... snip ...
>>>
There's no portable way to determine the maximum length of the
result of a "%p" *printf conversion.
.... snip ...
>>
I disagree, and published the following elsethread:

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice. The first time
replace the string with NULL and the size with 0. The returned
value will specify how many chars are needed. Add 1 (for the '\0'
mark), find or make a buffer with that space, and do the second
call.

If the items are likely to change between calls, copy them to
appropriate locations first. Then check and print from those.

Right, but I'm not sure what you're disagreeing with.
I disagreed with the first quoted sentence. If the pointer doesn't
change, its representation cannot change, since the representation
has to be capable of external storage, reading in with scanf, and
thus recreating the exact original pointer.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 7 '08 #115
Martien Verbruggen wrote:
CBFalconer <cb********@yahoo.comwrote:
>Nick Keighley wrote:
>>Richard Heathfield <r...@see.sig.invalidwrote:
.... snip ...
>>>
1) find out how much storage you need for the string;

how?

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice.
^^^^^^^^
I think you may have missed the point of the question.
You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 7 '08 #116
CBFalconer <cb********@yahoo.comwrites:
Keith Thompson wrote:
>CBFalconer <cb********@yahoo.comwrites:
>>Keith Thompson wrote:

... snip ...

There's no portable way to determine the maximum length of the
result of a "%p" *printf conversion.
... snip ...
>>>
I disagree, and published the following elsethread:

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice. The first time
replace the string with NULL and the size with 0. The returned
value will specify how many chars are needed. Add 1 (for the '\0'
mark), find or make a buffer with that space, and do the second
call.

If the items are likely to change between calls, copy them to
appropriate locations first. Then check and print from those.

Right, but I'm not sure what you're disagreeing with.

I disagreed with the first quoted sentence. If the pointer doesn't
change, its representation cannot change, since the representation
has to be capable of external storage, reading in with scanf, and
thus recreating the exact original pointer.
First off, a conforming implementation could, for example, say that
the "%p" conversion yields a random number of underscores followed by
the pointer representation in hexadecimal. *scanf would just ignore
the underscores. This would be a silly implementation, but I believe
it would be conforming.

Second, even assuming that each pointer value is converted to one and
only one string, what I meant was that there's no way to determine the
maximum length of the result of the "%p" conversion *over all possible
pointer values*.

Given the values of INT_MIN and INT_MAX, we can compute the maximum
length of the result of a "%d" conversion. No such computation is
possible for "%p".

In practice, there's (almost?) always an easily determined maximum
*for each implementation*.

But in the most general case, there's no value of N for which this:

char *foo(void *p)
{
static char buf[N];
sprintf(buf, "%p", p);
return buf;
}

can be guaranteed not to overflow buf.

Which is part of the reason that snprintf (if it's available) is so
useful: it at least lets you limit the consequences of guessing wrong
to truncation rather than undefined behavior.

--
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"
Aug 7 '08 #117
CBFalconer wrote:
Martien Verbruggen wrote:
>CBFalconer <cb********@yahoo.comwrote:
>>Nick Keighley wrote:
Richard Heathfield <r...@see.sig.invalidwrote:
... snip ...
>>>>
1) find out how much storage you need for the string;

how?

Assuming the parameters specifying the elements to be printed do
not change between the calls, call snprintf twice.
^^^^^^^^
I think you may have missed the point of the question.

You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.
I think that Nick Keighley was questioning how one would determine the
storage needed in the *absence* of snprintf (this is because Richard
Heathfield's numbered points were explaining the steps necessary to
correctly use sprintf, which implies that snprintf is not available for
use, for one reason or another.) And the answer was given by Richard
earlier in the thread: use fprintf with a temporary file and read back
the characters written (and match with the return value to be doubly
sure), then allocate the necessary storage for sprintf.

One disadvantage of this method is that it is not usable if the
environment of your program (i.e., the OS) does not allow the creation
of disk files, but only the access of existing ones. This would be the
case when the underlying filesystem is on a read-only media, as it
sometimes is. This doesn't render the C implementation non-conforming,
but it does mean that tmpfile might fail. Using snprintf avoids this
problem.

Aug 7 '08 #118
santosh said:

<snip>
I think that Nick Keighley was questioning how one would determine the
storage needed in the *absence* of snprintf (this is because Richard
Heathfield's numbered points were explaining the steps necessary to
correctly use sprintf, which implies that snprintf is not available for
use, for one reason or another.)
Right.
And the answer was given by Richard
earlier in the thread: use fprintf with a temporary file and read back
the characters written (and match with the return value to be doubly
sure), then allocate the necessary storage for sprintf.
That's about the only way I can think of for %p - it's normally a lot
simpler for other types.
One disadvantage of this method is that it is not usable if the
environment of your program (i.e., the OS) does not allow the creation
of disk files, but only the access of existing ones. This would be the
case when the underlying filesystem is on a read-only media, as it
sometimes is. This doesn't render the C implementation non-conforming,
but it does mean that tmpfile might fail.
Very true. There might not even /be/ a filesystem - C doesn't mandate one -
in which case tmpfile might not even be supplied as a standard library
function (i.e. we might be dealing with a freestanding implementation).
Using snprintf avoids this problem.
No, snprintf *doesn't* avoid the problem if, as you yourself say, "snprintf
is not available for use, for one reason or another", any more than a pet
dragon avoids the problem of lighting a campfire on a rainy day if the
dragon doesn't exist (or is otherwise occupied).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #119
santosh wrote:
CBFalconer wrote:
.... snip ...
>
>You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.
In that case I suggest using the %n feature in the format string.

7.19.6 Formatted input/output functions

[#1] The formatted input/output functions217) shall behave
as if there is a sequence point after the actions associated
with each specifier.

____________________

217The printf functions perform writes to memory for the %n
specifier.

.... snip ...

n The argument shall be a pointer to signed integer
into which is written the number of characters
written to the output stream so far by this call to
fprintf. No argument is converted, but one is
consumed. If the conversion specification includes
any flags, a field width, or a precision, the
behavior is undefined.

.... snip ...

7.19.6.6 The sprintf function

Synopsis
[#1]
#include <stdio.h>
int sprintf(char * restrict s,
const char * restrict format, ...);

Description

[#2] The sprintf function is equivalent to fprintf, except
that the output is written into an array (specified by the
argument s) rather than to a stream. A null character is
written at the end of the characters written; it is not
counted as part of the returned value. If copying takes
place between objects that overlap, the behavior is
undefined.

It may be that %n is not available in C90. If so the above is
hogwash.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 7 '08 #120
CBFalconer said:
santosh wrote:
>CBFalconer wrote:
... snip ...
>>
>>You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.

In that case I suggest using the %n feature in the format string.
How does that improve matters?
>
7.19.6 Formatted input/output functions

[#1] The formatted input/output functions217) shall behave
as if there is a sequence point after the actions associated
with each specifier.
Fine, but a bit too late by then if you're relying on %n to tell you how
much memory you should have allocated.

<snip>
It may be that %n is not available in C90.
It is available in C90.
If so the above is hogwash.
I think it's hogwash anyway. :-) But perhaps I've missed your point.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #121
CBFalconer wrote:
santosh wrote:
>CBFalconer wrote:
... snip ...
>>
>>You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.

In that case I suggest using the %n feature in the format string.
<snip>

For [v]printf and [v]sprintf the %n feature is useless, because if the
buffer was not large enough, buffer overrun would already have occured
by the time the %n is encountered, and thus further correctness cannot
be relied upon.

For [v]fprintf the %n feature does exactly the same thing as the return
value (provided it is last in the format string of course), but is more
cumbersome to use, and I may be wrong, but I think it cannot be easily
used vfprintf anyway.

Aug 7 '08 #122
On Aug 6, 4:02 pm, s0s...@gmail.com wrote:
On Aug 6, 12:31 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Keith Thompson said:
<snip>
There's no portable way to determine the maximum length of the result
of a "%p" *printf conversion.
Right.
With snprintf, you can make a reasonable guess. The consequence of
guessing wrong is that the resulting string is truncated, and you can
either accept that or try again with a bigger buffer.
Right.
Even if you're
given an even bigger string on the second attempt, the consequences
are still no worse than a truncated result.
Right.
With sprintf, you can make a reasonable guess, but the consequence of
guessing wrong is undefined behavior.
If we're allowed a preliminary length-determining operation (as in your
first call to snprintf), we can use fprintf to write the pointer's text
representation to a temporary file and, at the same time, find out how
long it is; then we can seek back in the file and read from the file into
the string. Easy.
And even for integer and floating-point arguments, where you can (I
think) portably determine the maximum length, getting it right is
still a tedious and error-prone process.
No, not really. We can say "our application is required to support values
in such-and-such a range, so we'll do that, and perhaps provide a bit of
leeway, and then we'll treat anything that won't fit as an exception to be
reported upon and investigated, but in the meantime we're not going to
accept it as part of our string". We have to do this anyway for other
reasons - for example, if we're dealing with ages of living humans we
don't bother supporting ages of, say, 1000+ - so we range-check it and use
%3d and don't care that our super-amazing-ints can hold 85-digit values
because we still only spec three bytes for the text rep of the age value.
(Yes, I know we need one more for the null character.) If we come across
an age of 1000+, we flag that record as needing attention and we move on
to other things /without/ printing it.

Seems like it's a bit hard to reason with Richard, so let's move onto
practice a bit...

Coincidentally, just a while ago I found myself using snprintf() in a
program to turn a number into a string:

...
size_t serviceLen = 5;
char *service = malloc(sizeof(char) * serviceLen);
if (service == NULL)
return FTT_ERROR_OUT_OF_MEMORY;

while (snprintf(service, serviceLen, "%d", port) >= serviceLen) {
serviceLen += 5;
char *new = realloc(service, sizeof(char) * serviceLen);
if (new == NULL) {
free(service);
return FTT_ERROR_OUT_OF_MEMORY;
}

service = new;
}

...
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:

....
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
....

Sebastian
Aug 7 '08 #123
s0****@gmail.com wrote:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:

...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
That should be:

snprintf(service, serviceLen+1, "%d", port);

or the last character will be discarded.

Aug 7 '08 #124
s0****@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:

...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #125
On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
Isn't 'service' a VLA? (because of sizeof)
Aug 7 '08 #126
On Aug 7, 5:42 am, santosh <santosh....@gmail.comwrote:
s0s...@gmail.com wrote:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

That should be:

snprintf(service, serviceLen+1, "%d", port);

or the last character will be discarded.
Right! Thanks.

Sebastian

Aug 7 '08 #127
vi******@gmail.com said:
On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>s0s...@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

Isn't 'service' a VLA? (because of sizeof)
No. The sizeof operator's result is evaluated during translation, and
yields a constant integer expression that you can use to define the size
of an ordinary C90 array.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #128
On Aug 7, 5:53 am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
What does the operation calculate? If it's the max number of digits
that an int can represent: wouldn't that allocate more space that
might be needed? If not: wouldn't that cause the call to sprintf() to
be insecure?

Sebastian

Aug 7 '08 #129
vi******@gmail.com writes:
On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>s0s...@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better. This
is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

Isn't 'service' a VLA? (because of sizeof)
No. 6.6.6:

"An integer constant expression shall have integer type and shall
only have operands 6 that are integer constants, enumeration
constants, character constants, sizeof expressions whose results are
integer constants, and floating constants that are the immediate
operands of casts. Cast operators in an integer constant expression
shall only convert arithmetic types to integer types, except as part
of an operand to the sizeof operator."

You are probably thinking of the expressions allowed in #if. These
can't use sizeof except as an identifier that will be replaced by the
pp-token 0.

--
Ben.
Aug 7 '08 #130
s0****@gmail.com wrote:
On Aug 7, 5:53 am, Richard Heathfield <r...@see.sig.invalidwrote:
>s0s...@gmail.com said:

<snip>
Never mind. The approach described by CBFalconer is much better.
This is what it would boil down to:
...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine)
and more portable (because it doesn't depend on either VLAs or
snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

What does the operation calculate? If it's the max number of digits
that an int can represent: wouldn't that allocate more space that
might be needed?
It might, but that extra space will be trivially small unless your int
happens to be able to hold hundreds or thousands of digits. :-)
If not: wouldn't that cause the call to sprintf() to
be insecure?
It isn't, but separate routines will be needed for other bases, or you
might just allocate space for a binary representation and use that for
all other bases.

Aug 7 '08 #131
Richard Heathfield wrote:
vi******@gmail.com said:
>On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>>s0s...@gmail.com said:

<snip>

Never mind. The approach described by CBFalconer is much better.
This is what it would boil down to:

...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine)
and more portable (because it doesn't depend on either VLAs or
snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

Isn't 'service' a VLA? (because of sizeof)

No. The sizeof operator's result is evaluated during translation, and
yields a constant integer expression that you can use to define the
size of an ordinary C90 array.
Sizeof is available during the later stages of translation, but
unfortunately, it's not available during the preprocessing stages.

Aug 7 '08 #132
santosh wrote:
Richard Heathfield wrote:
>vi******@gmail.com said:
>>On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:

<snip>

Never mind. The approach described by CBFalconer is much better.
This is what it would boil down to:

...
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building
routine) and more portable (because it doesn't depend on either
VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

Isn't 'service' a VLA? (because of sizeof)

No. The sizeof operator's result is evaluated during translation, and
yields a constant integer expression that you can use to define the
size of an ordinary C90 array.

Sizeof is available during the later stages of translation, but
unfortunately, it's not available during the preprocessing stages.
Sorry. I misdirected this post to you. I meant it for vippstar. Please
ignore.

Aug 7 '08 #133
s0****@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <r...@see.sig.invalidwrote:
>s0s...@gmail.com said:
<snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);

Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:

char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

What does the operation calculate?
The maximum number of decimal digits an int can represent, plus one for the
sign and one for the null terminator.
If it's the max number of digits
that an int can represent:
Right.
wouldn't that allocate more space that might be needed?
It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33 bits
in a byte) and sizeof(int) is 5, with no padding bits and one sign bit, we
have 164 value bits (and 1 sign bit), so INT_MAX is a fifty-digit number
(in fact it's 23384026197294446691258957323460528314494920687615 ), and my
expression (excluding provision for the sign byte and the null byte)
yields 166 / 3 = 55, so a massive five bytes are wasted.

Feel free to devise a better algorithm, bearing in mind that you can't take
logs or do anything else that involves runtime evaluation (because
otherwise it won't be a constant integer expression and therefore it won't
be suitable for sizing a C90 array).

If not: wouldn't that cause the call to sprintf() to be insecure?
Irrelevant, since it is always sufficient.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #134
Richard Heathfield <rj*@see.sig.invalidwrites:
s0****@gmail.com said:
>On Aug 7, 5:53 am, Richard Heathfield <r...@see.sig.invalidwrote:
<snip>
>>char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);

What does the operation calculate?

The maximum number of decimal digits an int can represent, plus one for the
sign and one for the null terminator.
<snip>
>wouldn't that allocate more space that might be needed?

It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33 bits
in a byte) and sizeof(int) is 5, with no padding bits and one sign bit, we
have 164 value bits (and 1 sign bit), so INT_MAX is a fifty-digit number
(in fact it's 23384026197294446691258957323460528314494920687615 ), and my
expression (excluding provision for the sign byte and the null byte)
yields 166 / 3 = 55, so a massive five bytes are wasted.
I suspect he's worrying about the 54 wasted bytes when converting 0.
To s0suk3: use the return from sprintf to malloc the correct space.
In your original you wanted a freeable return value, so this local
array is always going to be just a temporary buffer.

--
Ben.
Aug 7 '08 #135
On Aug 7, 7:04 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
<snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
Faster (because it makes only one call to a string-building routine) and
more portable (because it doesn't depend on either VLAs or snprintf) is:
char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
What does the operation calculate?

The maximum number of decimal digits an int can represent, plus one for the
sign and one for the null terminator.
If it's the max number of digits
that an int can represent:

Right.
wouldn't that allocate more space that might be needed?

It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33 bits
in a byte) and sizeof(int) is 5, with no padding bits and one sign bit, we
have 164 value bits (and 1 sign bit), so INT_MAX is a fifty-digit number
(in fact it's 23384026197294446691258957323460528314494920687615 ), and my
expression (excluding provision for the sign byte and the null byte)
yields 166 / 3 = 55, so a massive five bytes are wasted.

Feel free to devise a better algorithm, bearing in mind that you can't take
logs or do anything else that involves runtime evaluation (because
otherwise it won't be a constant integer expression and therefore it won't
be suitable for sizing a C90 array).
Why does it have to be a C90 array? You can always use either a VLA,
or malloc() if you don't have access to a C99 compiler (unlikely). As
for calculating the required length, I don't think there's a better or
more elegant way than calling snprintf() twice (which I don't think
imposes much overhead, do you?).

<snip>

Sebastian

Aug 7 '08 #136
Ben Bacarisse said:
Richard Heathfield <rj*@see.sig.invalidwrites:
>s0****@gmail.com said:
<snip>
>>wouldn't that allocate more space that might be needed?

It's possible, yes. For example, if CHAR_BIT is 33 [...] and
sizeof(int) is 5, with no padding bits and one sign bit, [...]
INT_MAX is a fifty-digit number [...] and my expression
[...] yields 166 / 3 = 55, so a massive five bytes are wasted.

I suspect he's worrying about the 54 wasted bytes when converting 0.
Ah, I see - well, he probably isn't using a 33-bit char, 5-byte int
implementation anyway. On a more normal implementation with CHAR_BIT at 8
and sizeof(int) at 4, we get 34 / 3 = 11, which wastes 10 bytes
(temporarily) if the value happens to be 0, but just one if the value is a
ten-decimal-digit number.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #137
On Aug 7, 2:20 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
vipps...@gmail.com writes:
On Aug 7, 1:53 pm, Richard Heathfield <r...@see.sig.invalidwrote:
char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
Isn't 'service' a VLA? (because of sizeof)

No. 6.6.6:

"An integer constant expression shall have integer type and shall
only have operands 6 that are integer constants, enumeration
constants, character constants, sizeof expressions whose results are
integer constants, and floating constants that are the immediate
operands of casts. Cast operators in an integer constant expression
shall only convert arithmetic types to integer types, except as part
of an operand to the sizeof operator."

You are probably thinking of the expressions allowed in #if. These
can't use sizeof except as an identifier that will be replaced by the
pp-token 0.
Ah thanks. Now that santosh mentioned the value being available in
later TPs it makes more sense to me.

6.6.6 :-)
Aug 7 '08 #138
s0****@gmail.com said:
On Aug 7, 7:04 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
<snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
>Faster (because it makes only one call to a string-building routine)
and more portable (because it doesn't depend on either VLAs or
snprintf) is:
>char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
What does the operation calculate?

The maximum number of decimal digits an int can represent, plus one for
the sign and one for the null terminator.
If it's the max number of digits
that an int can represent:

Right.
wouldn't that allocate more space that might be needed?

It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33
bits in a byte) and sizeof(int) is 5, with no padding bits and one sign
bit, we have 164 value bits (and 1 sign bit), so INT_MAX is a
fifty-digit number (in fact it's
2338402619729444669125895732346052831449492068761 5), and my expression
(excluding provision for the sign byte and the null byte) yields 166 / 3
= 55, so a massive five bytes are wasted.

Feel free to devise a better algorithm, bearing in mind that you can't
take logs or do anything else that involves runtime evaluation (because
otherwise it won't be a constant integer expression and therefore it
won't be suitable for sizing a C90 array).

Why does it have to be a C90 array?
Because it's convenient to be able to do this with C90 arrays.
You can always use either a VLA,
Maybe you can. I can't, and neither can anyone else who can't risk the
portability issues inherent in using C99 features.
or malloc()
How is that an advantage over a C90 array?
if you don't have access to a C99 compiler (unlikely).
Hardly anyone has access to a C99 implementation. Microsoft don't do one.
Borland don't do one. GNU don't do one. That's a huge proportion of the C
marketplace right there.
As
for calculating the required length, I don't think there's a better or
more elegant way than calling snprintf() twice
If snprintf isn't there, it's hard to see how calling it is even possible,
let alone desirable. And if it /is/ there, you gain nothing (and may lose
a little) by calling it twice, compared to calling it once and sprintf
once.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #139
s0****@gmail.com wrote:
On Aug 7, 7:04 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
<snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
>Faster (because it makes only one call to a string-building
routine) and more portable (because it doesn't depend on either
VLAs or snprintf) is:
>char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
What does the operation calculate?

The maximum number of decimal digits an int can represent, plus one
for the sign and one for the null terminator.
If it's the max number of digits
that an int can represent:

Right.
wouldn't that allocate more space that might be needed?

It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33
bits in a byte) and sizeof(int) is 5, with no padding bits and one
sign bit, we have 164 value bits (and 1 sign bit), so INT_MAX is a
fifty-digit number (in fact it's
2338402619729444669125895732346052831449492068761 5), and my
expression (excluding provision for the sign byte and the null byte)
yields 166 / 3 = 55, so a massive five bytes are wasted.

Feel free to devise a better algorithm, bearing in mind that you
can't take logs or do anything else that involves runtime evaluation
(because otherwise it won't be a constant integer expression and
therefore it won't be suitable for sizing a C90 array).

Why does it have to be a C90 array?
So that you don't have to be worried about portability.
You can always use either a VLA, or malloc()
True, but this involves writing conditional code with #if #else #endif,
which is at best, repetitive and tedious and tends to drastically
affect code readability.
if you don't have access to a C99 compiler (unlikely).
Really? How many fully conformant C99 compilers are out there? I can
think of about four or five and none that are open source.

But more to the point, Richard has previously indicated quite often,
that he requires his own code to be widely portable across mainframes,
minis, micros etc. I doubt that there exists a C99 compiler that can
satisfy his requirements. Fortunately not everyone needs the same level
of portability though. If you know that your program will only ever be
used on desktops, then you can take C99 a lot more seriously.
As for calculating the required length, I don't think there's a better
or more elegant way than calling snprintf() twice (which I don't think
imposes much overhead, do you?).
It's not a question of overhead at all. Snprintf is simply not an option
to those aiming for strict C90 compliance, like Richard, unless if they
were to roll their own.

Aug 7 '08 #140
Richard Heathfield wrote:
CBFalconer said:
>santosh wrote:
>>CBFalconer wrote:
... snip ...
>>>
You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.

In that case I suggest using the %n feature in the format string.

How does that improve matters?
Use the null device to receive the testing run. Most systems have
such a device available.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 7 '08 #141
On Aug 7, 7:49 am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:
On Aug 7, 7:04 am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <r...@see.sig.invalidwrote:
s0s...@gmail.com said:
<snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
Faster (because it makes only one call to a string-building routine)
and more portable (because it doesn't depend on either VLAs or
snprintf) is:
char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
sprintf(service, "%d", port);
What does the operation calculate?
The maximum number of decimal digits an int can represent, plus one for
the sign and one for the null terminator.
If it's the max number of digits
that an int can represent:
Right.
wouldn't that allocate more space that might be needed?
It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33
bits in a byte) and sizeof(int) is 5, with no padding bits and one sign
bit, we have 164 value bits (and 1 sign bit), so INT_MAX is a
fifty-digit number (in fact it's
23384026197294446691258957323460528314494920687615 ), and my expression
(excluding provision for the sign byte and the null byte) yields 166 / 3
= 55, so a massive five bytes are wasted.
Feel free to devise a better algorithm, bearing in mind that you can't
take logs or do anything else that involves runtime evaluation (because
otherwise it won't be a constant integer expression and therefore it
won't be suitable for sizing a C90 array).
Why does it have to be a C90 array?

Because it's convenient to be able to do this with C90 arrays.
You can always use either a VLA,

Maybe you can. I can't, and neither can anyone else who can't risk the
portability issues inherent in using C99 features.
Let's not start another C89/C90/C99 was, as it seems to happen
everyday around here. But for the sake of argument: *what* do you
deploy in (if I may know)? I've always used GNU GCC's C99
implementation... I know, I know, they don't claim full C99
conformance. But that's a fact that's never affected me in any way so
far.
or malloc()

How is that an advantage over a C90 array?
In this particular case it's obvious, isn't it? That you can use
runtime evaluation to calculate the required size.
if you don't have access to a C99 compiler (unlikely).

Hardly anyone has access to a C99 implementation. Microsoft don't do one.
Borland don't do one. GNU don't do one. That's a huge proportion of the C
marketplace right there.
As
for calculating the required length, I don't think there's a better or
more elegant way than calling snprintf() twice

If snprintf isn't there, it's hard to see how calling it is even possible,
let alone desirable. And if it /is/ there, you gain nothing (and may lose
a little) by calling it twice, compared to calling it once and sprintf
once.
Well, by calling

snprintf() twice,
you gain the assurance of allocating the right size without the
danger of overflow or the inconvenient need to make inaccurate
guesses. By calling

snprintf() once,
you gain the assurance of no overflow, but you still might need to
make inaccurate size guesses. And by calling

sprintf() once,
you gain neither one of those :(

Sebastian

Aug 7 '08 #142
On Aug 7, 8:16 am, s0****@gmail.com wrote:
On Aug 7, 7:49 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:
On Aug 7, 7:04 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
On Aug 7, 5:53 am, Richard Heathfield <rj*@see.sig.invalidwrote:
>s0****@gmail.com said:
><snip>
int serviceLen = snprintf(NULL, 0, "%d", port);
char service[serviceLen + 1];
snprintf(service, serviceLen, "%d", port);
>Faster (because it makes only one call to a string-building routine)
>and more portable (because it doesn't depend on either VLAs or
>snprintf) is:
>char service[(sizeof(int) * CHAR_BIT + 2) / 3 + 2];
>sprintf(service, "%d", port);
What does the operation calculate?
>The maximum number of decimal digits an int can represent, plus one for
>the sign and one for the null terminator.
If it's the max number of digits
that an int can represent:
>Right.
wouldn't that allocate more space that might be needed?
>It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33
>bits in a byte) and sizeof(int) is 5, with no padding bits and one sign
>bit, we have 164 value bits (and 1 sign bit), so INT_MAX is a
>fifty-digit number (in fact it's
>2338402619729444669125895732346052831449492068761 5), and my expression
>(excluding provision for the sign byte and the null byte) yields 166 / 3
>= 55, so a massive five bytes are wasted.
>Feel free to devise a better algorithm, bearing in mind that you can't
>take logs or do anything else that involves runtime evaluation (because
>otherwise it won't be a constant integer expression and therefore it
>won't be suitable for sizing a C90 array).
Why does it have to be a C90 array?
Because it's convenient to be able to do this with C90 arrays.
You can always use either a VLA,
Maybe you can. I can't, and neither can anyone else who can't risk the
portability issues inherent in using C99 features.

Let's not start another C89/C90/C99 was,
I meant war...
as it seems to happen
everyday around here. But for the sake of argument: *what* do you
deploy in (if I may know)?
Never mind; Santosh already answered that.

<snip>

Sebastian

Aug 7 '08 #143
CBFalconer <cb********@yahoo.comwrites:
Richard Heathfield wrote:
>CBFalconer said:
>>santosh wrote:
CBFalconer wrote:

... snip ...

You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.

In that case I suggest using the %n feature in the format string.

How does that improve matters?

Use the null device to receive the testing run. Most systems have
such a device available.
Most systems? Oh dear me Chuck. You break your own rules by your own
admission. Off topic. Non portable. "We do not discuss such things here"
is what, I believe, you would tell everyone else.

Aug 7 '08 #144
CBFalconer said:
Richard Heathfield wrote:
>CBFalconer said:
<snip>
>>>
In that case I suggest using the %n feature in the format string.

How does that improve matters?

Use the null device to receive the testing run.
This doesn't answer the question. How does %n improve matters?
Most systems have such a device available.
I can find nothing in the Standard on "null device". Could you please
provide C&V?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #145
s0****@gmail.com said:

<snip>
Let's not start another C89/C90/C99 was, as it seems to happen
everyday around here. But for the sake of argument: *what* do you
deploy in (if I may know)?
Much of my code is deployed as source. My users can use any conforming C
compiler they like; whether it's C90- or C99-conforming is of no
consequence.
I've always used GNU GCC's C99 implementation...
They haven't got one.
I know, I know, they don't claim full C99 conformance.
Well, as long as you know.
But that's a fact that's never affected me in any way so far.
Pull the ladder up, Jack! :-)
or malloc()

How is that an advantage over a C90 array?

In this particular case it's obvious, isn't it? That you can use
runtime evaluation to calculate the required size.
I don't see why it's advantageous to postpone until runtime a calculation
that can be performed trivially at compilation time. There are
circumstances where it is advantageous to use malloc, but I don't see this
as one of them.

<snip>
>If snprintf isn't there, it's hard to see how calling it is even
possible, let alone desirable. And if it /is/ there, you gain nothing
(and may lose a little) by calling it twice, compared to calling it once
and sprintf once.

Well, by calling snprintf() twice,
you gain the assurance of allocating the right size without the
danger of overflow or the inconvenient need to make inaccurate
guesses.
Assuming you have snprintf, you get that assurance even if you call it once
and then follow up with a call to sprintf.

By calling snprintf() once,
you gain the assurance of no overflow, but you still might need to
make inaccurate size guesses.
No, you get the right size with your first call...
And by calling sprintf() once,
....you use a buffer of that right size to hand to sprintf.
you gain neither one of those :(
Ah, I think I understand what you thought I meant. You seem to think that
(given a C99 implementation to work with) I'm offering you three choices:

(1a) snprintf twice
(1b) snprintf once
(1c) sprintf once

I wasn't. I was offering you *two* choices:

(2a) snprintf twice
(2b) snprintf once (to get the size), followed by buffer provision,
followed by sprintf

It is my contention that (2b) is superior to (2a). It is my further
contention that (2b) is not optimal, but we've already had that fight,
right?

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 7 '08 #146
CBFalconer wrote:
Richard Heathfield wrote:
>CBFalconer said:
>>santosh wrote:
CBFalconer wrote:

... snip ...

You can always replace the second call to snprintf with a call to
sprintf. The method answers Mr Keighleys 'how' response.

I think that Nick Keighley was questioning how one would determine
the storage needed in the *absence* of snprintf (this is because
Richard Heathfield's numbered points were explaining the steps
necessary to correctly use sprintf, which implies that snprintf is
not available for use, for one reason or another.) And the answer
was given by Richard earlier in the thread: use fprintf with a
temporary file and read back the characters written (and match
with the return value to be doubly sure), then allocate the
necessary storage for sprintf.

In that case I suggest using the %n feature in the format string.

How does that improve matters?

Use the null device to receive the testing run. Most systems have
such a device available.
I strongly suspect that snprintf itself is more widely available than
a "null device". Thus using a "null device" is almost certainly less
portable than using snprintf.

Aug 7 '08 #147
Richard Heathfield wrote:
s0****@gmail.com said:
>In this particular case it's obvious, isn't it? That you can use
runtime evaluation to calculate the required size.

I don't see why it's advantageous to postpone until runtime a
calculation that can be performed trivially at compilation time.
Would it be as trivial for, say, a long double? I have had cases where
the same long double object produced an output of several lines of
digits for some values and just a few digits for others. Is there a
deterministic formula for doing this at compile-time based only on the
information derivable from float.h?

<snip>
Ah, I think I understand what you thought I meant. You seem to think
that (given a C99 implementation to work with) I'm offering you three
choices:

(1a) snprintf twice
(1b) snprintf once
(1c) sprintf once

I wasn't. I was offering you *two* choices:

(2a) snprintf twice
(2b) snprintf once (to get the size), followed by buffer provision,
followed by sprintf

It is my contention that (2b) is superior to (2a).
How? 2b isn't any more portable than 2a, and it *might* be
infinitesimally faster. No data loss occurs in either case. So why is
2b superior to 2a?
It is my further contention that (2b) is not optimal, but we've
already had that fight, right?
Agreed.

Aug 7 '08 #148
On Thu, 07 Aug 2008 12:04:42 +0000, Richard Heathfield wrote:

The maximum number of decimal digits an int can represent, plus one for
the sign and one for the null terminator.
sizeof(int) on my machine is 4 and I tried your expression 4 times:
printf( "max_of_int = %d\n", ( (sizeof(int)* CHAR_BIT) +2 / 3 + 2 ));
printf( "max_of_int = %d\n", ( ((sizeof(int)* CHAR_BIT)) + (2 / 3) + 2) );
printf( "max_of_int = %d\n", ( ( ((sizeof(int)* CHAR_BIT) +2) / 3) + 2) );
printf( "max_of_int = %d\n", ( ((sizeof(int)* CHAR_BIT) +2) / (3 + 2) ));
so, 1st printf() is yours and the only match is second. I will takeit
part by part:

sizeof(int)*CHAR_BIT

why are you multiplying the "size of an int" with "how many bits
in a char" ?

2/3 , it gives what, i mean why it is there ?

+ 2 - okay, one for null character and one for sign

It's possible, yes. For example, if CHAR_BIT is 33 (i.e. there are 33
bits in a byte)
and what normal desktop machine have that value, Intel Dual Core, AMD
Athlon 64 3000+ ?
with no padding bits and one sign
bit, we have 164 value bits (and 1 sign bit), so INT_MAX is a
fifty-digit number (in fact it's
23384026197294446691258957323460528314494920687615 ), and my expression
(excluding provision for the sign byte and the null byte) yields 166 / 3
= 55, so a massive five bytes are wasted.

Feel free to devise a better algorithm, bearing in mind that you can't
take logs or do anything else that involves runtime evaluation (because
otherwise it won't be a constant integer expression and therefore it
won't be suitable for sizing a C90 array).
Irrelevant, since it is always sufficient.

hahahaha... It feels like 2 aliens are talking to each other in some
mysterious language...

I did not laugh because of two aliens. Laughing part is "I am paid to
write C Code" when I can't understand your conversation..

and I call myself a Programmer... huh...

--
www.lispmachine.wordpress.com
my email is @ the above blog
check the "About Myself" page

Aug 7 '08 #149
On Aug 7, 8:58 am, Richard Heathfield <rj*@see.sig.invalidwrote:
s0****@gmail.com said:

<snip>
Let's not start another C89/C90/C99 was, as it seems to happen
everyday around here. But for the sake of argument: *what* do you
deploy in (if I may know)?

Much of my code is deployed as source. My users can use any conforming C
compiler they like; whether it's C90- or C99-conforming is of no
consequence.
I've always used GNU GCC's C99 implementation...

They haven't got one.
I know, I know, they don't claim full C99 conformance.

Well, as long as you know.
But that's a fact that's never affected me in any way so far.

Pull the ladder up, Jack! :-)
or malloc()
How is that an advantage over a C90 array?
In this particular case it's obvious, isn't it? That you can use
runtime evaluation to calculate the required size.

I don't see why it's advantageous to postpone until runtime a calculation
that can be performed trivially at compilation time. There are
circumstances where it is advantageous to use malloc, but I don't see this
as one of them.

<snip>
If snprintf isn't there, it's hard to see how calling it is even
possible, let alone desirable. And if it /is/ there, you gain nothing
(and may lose a little) by calling it twice, compared to calling it once
and sprintf once.
Well, by calling snprintf() twice,
you gain the assurance of allocating the right size without the
danger of overflow or the inconvenient need to make inaccurate
guesses.

Assuming you have snprintf, you get that assurance even if you call it once
and then follow up with a call to sprintf.
By calling snprintf() once,
you gain the assurance of no overflow, but you still might need to
make inaccurate size guesses.

No, you get the right size with your first call...
And by calling sprintf() once,

...you use a buffer of that right size to hand to sprintf.
you gain neither one of those :(

Ah, I think I understand what you thought I meant. You seem to think that
(given a C99 implementation to work with) I'm offering you three choices:

(1a) snprintf twice
(1b) snprintf once
(1c) sprintf once

I wasn't. I was offering you *two* choices:

(2a) snprintf twice
(2b) snprintf once (to get the size), followed by buffer provision,
followed by sprintf
I see. But if you call snprintf() first to tell you the size, it's
completely irrelevant whether in the second call you use sprintf() or
snprintf(); it's merely a matter of implicitness or explicitness.
(Small exception: as CBFalconer mentioned, if, for some reason, the
value to be converted might change between the two calls, being
explicit about the size and using snprintf() for the second call would
be safer.)

<snip>

Sebastian

Aug 7 '08 #150

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Ken Lindner | last post by:
I have a need to become familiar with SQL Server 2000 for work. Needless to say I am new to SQL Server any version, but not IT in general. My employer has provided me with the SQL Server 2000...
7
by: lvpaul | last post by:
Hallo ! I am using IIS-Windows-Authentication in my intranet (web.config <authentication mode="Windows" /> <identity impersonate="true" /> How can I get the users (client) IP-Address ? I...
7
by: Tyler Foreman | last post by:
Hello, I have a strange problem that occurs every so often in my application. It usually takes place when I hide one form and activate another. What happens is I get the following exception:...
1
by: Scott Davies | last post by:
Hi, I'm looking for some help on a small program that I'm trying to develop in VB.NET. I'm having trouble getting the code that I've written to work, can anyone shed some light as to where I'm...
0
by: Scott Davies | last post by:
Hi, I'm looking for some help on a small program that I'm trying to develop in VB.NET. The program I'm trying to develop needs to be able to do the following: - Select remote server -...
4
by: Rod Gill | last post by:
Hi, I have a form that when opened in the designer appears of the screen. The form selector can't be dragged (or resized) and if I scroll right and down to centralise it the form simply jumps...
2
by: sambo251 | last post by:
After running a few updates I get this very annoying "Windows Installer" error #1706 that will ne go away! It keeps saying that it cannot find the file "instantsharedevices.msi", that it is on...
1
by: mfunkmann | last post by:
Hi, I recently got an error and I don't know how to fix it: Error 1 'System.Data.DataColumn' does not contain a definition for 'Windows' C:\c#\CsharpPRO\Form1.Designer.cs 304 77 CsharpPRO I...
0
AmberJain
by: AmberJain | last post by:
Windows Autorun FAQs: List of autostart locations Linked from the Original article- "Windows Autorun FAQs: Description". Que: Can you list all the autostart locations for windows? Ans: Here is...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.