-
January 23rd, 2004, 08:06 AM
#1
*void -> *short ?????
Hi everyone. Suppose the following code:
Code:
void *var;
int c; // c given by user...
...
...
switch (c)
{
case 1:
var = (short*)malloc(sizeof(short));
scanf("%d",(short*)var);
printf("content of var: %d\n",*(short*)var);
break;
case 2: // same for float
...
...
...
}
The above program works fine with all types (int, float, double) but not for short. I suppose %d for shorts is not right undes Solaris 5.7?
-
January 23rd, 2004, 08:36 AM
#2
Have you tried the following?
Code:
printf("content of var: %hd\n",*(short*)var);
-
January 23rd, 2004, 08:54 AM
#3
thanx alot marc G. It works fine, though i haven't found something like that in man scanf.
-
January 23rd, 2004, 09:45 AM
#4
It's a MS-specifc extension it says on MSDN, but maybe other compilers also allow it.
It means that the stuff which follows is a short, not a long. Another (a bit complicated, I agree) method of doing it would be:
Code:
printf("content of var: %d\n",int(*(short*)var));
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
January 23rd, 2004, 09:51 AM
#5
that works in visual studio, but doesn/t work in gcc (of solaris 5.7).
Thanx anyway
-
January 23rd, 2004, 10:44 AM
#6
I don't agree that %hd is MS-specific. In fact it is common to all the OS I have worked with, including Solaris and Linux.
-
January 23rd, 2004, 01:12 PM
#7
Originally posted by yiannakop
that works in visual studio, but doesn/t work in gcc (of solaris 5.7).
Thanx anyway
Really ? I'm surprised... Which version of ggc are you using? The cast to int should 'lengthen' the value of the short, so that it gets passed as the correct type (%d) of va_arg.
I don't agree that %hd is MS-specific. In fact it is common to all the OS I have worked with, including Solaris and Linux.
Maybe not. It just says on MSDN that it's MS-specific.
MSDN
The optional prefixes to type, h, l, and L, specify the “size” of argument (long or short, single-byte character or wide character, depending upon the type specifier that they modify). These type-specifier prefixes are used with type characters in printf functions or wprintf functions to specify interpretation of arguments, as shown in the following table. These prefixes are Microsoft extensions and are not ANSI-compatible.
Maybe it's in the C99 standard. I don't have it, so I can't really tell.
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
January 23rd, 2004, 01:29 PM
#8
First of all, I believe the problem lies more with scanf() than printf(). When specifying variable length arguments, certain data types are promoted. floats to doubles and shorts to ints. The problem really lies with scanf(). It is here that "%hd" must be specified.
As far as the "h" being Microsoft specific, MSDN says that using "h" with character types is MS-specific. i.e. "%hc" I believe that "%hd" is probably (I don't have the standard in front of me) standard C.
- Kevin
-
January 23rd, 2004, 01:51 PM
#9
Originally posted by KevinHall
First of all, I believe the problem lies more with scanf() than printf(). When specifying variable length arguments, certain data types are promoted. floats to doubles and shorts to ints. The problem really lies with scanf(). It is here that "%hd" must be specified.
True. The statement scanf("%d",(short*)var) will result in overwriting memory past the end of the memory allocated for var.
Thinking about it, the original printf("%d") statement is entirely correct. There is no need for %hd in there nor for a conversion to int, since the compiler will upgrade the dereferenced value of var to an int automatically. So it's just the scanf that's wrong.
Last edited by Yves M; January 23rd, 2004 at 01:59 PM.
Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
Supports C++ and VB out of the box, but can be configured for other languages.
-
January 23rd, 2004, 02:03 PM
#10
The 'h' modifier is not a microsoft extension, see below for quote from the C99 draft:
Code:
[#7] The length modifiers and their meanings are:
hh Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a signed char
or unsigned char argument (the argument will
have been promoted according to the integer
promotions, but its value shall be converted to
signed char or unsigned char before printing);
or that a following n conversion specifier
applies to a pointer to a signed char argument.
h Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a short int or
unsigned short int argument (the argument will
have been promoted according to the integer
promotions, but its value shall be converted to
short int or unsigned short int before
printing); or that a following n conversion
specifier applies to a pointer to a short int
argument.
l (ell) Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a long int or
unsigned long int argument; that a following n
conversion specifier applies to a pointer to a
long int argument; that a following c
conversion specifier applies to a wint_t
argument; that a following s conversion
specifier applies to a pointer to a wchar_t
argument; or has no effect on a following a, A,
e, E, f, F, g, or G conversion specifier.
ll (ell-ell) Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a long long int
or unsigned long long int argument; or that a
following n conversion specifier applies to a
pointer to a long long int argument.
j Specifies that a following d, i, o, u, x, or X
conversion specifier applies to an intmax_t or
uintmax_t argument; or that a following n
conversion specifier applies to a pointer to an
intmax_t argument.
z Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a size_t or the
corresponding signed integer type argument; or
that a following n conversion specifier applies
to a pointer to a signed integer type
corresponding to size_t argument.
t Specifies that a following d, i, o, u, x, or X
conversion specifier applies to a ptrdiff_t or
the corresponding unsigned integer type
argument; or that a following n conversion
specifier applies to a pointer to a ptrdiff_t
argument.
L Specifies that a following a, A, e, E, f, F, g,
or G conversion specifier applies to a long
double argument.
-
January 23rd, 2004, 02:26 PM
#11
Originally posted by Marc G
The 'h' modifier is not a microsoft extension, see below for quote from the C99 draft:
This doesn't prove or disprove whether it is a Microsoft extension if we are talking about C++ programs. The C++ standard is not the same as the C99 standard. For example, in the C99 standard you have variable sized arrays, which is non-existant in the C++ standard. Some C++ compilers do offer variable sized arrays, but this is an extension.
Regards,
Paul McKenzie
Last edited by Paul McKenzie; January 23rd, 2004 at 02:29 PM.
-
January 23rd, 2004, 02:48 PM
#12
Originally posted by Paul McKenzie
This doesn't prove or disprove whether it is a Microsoft extension if we are talking about C++ programs. The C++ standard is not the same as the C99 standard.
Does this mean that it's possible for the printf family of functions to be different in the C++ standard versus the C standard? I sure hope not.
-
January 23rd, 2004, 02:51 PM
#13
Originally posted by Marc G
Does this mean that it's possible for the printf family of functions to be different in the C++ standard versus the C standard? I sure hope not.
Yes...that's what it means. The C99 standard is being worked on apart from the C++, however, most-likely the next C++ standard will implement these kind of things as well...
-
January 23rd, 2004, 03:04 PM
#14
Originally posted by Marc G
Does this mean that it's possible for the printf family of functions to be different in the C++ standard versus the C standard?
Originally posted by Andreas Masur
Yes...that's what it means.
Although they are allowed to, I would not think that most compilers would implement two different versions of printf() et. al. for C and C++. More likely is that a compiler will not be in full compliance with one of the languages. MSVC++.NET for example has chosen to not support C99 (at least for the time being).
-
January 23rd, 2004, 03:10 PM
#15
Originally posted by KevinHall
Although they are allowed to, I would not think that most compilers would implement two different versions of printf() et. al. for C and C++. More likely is that a compiler will not be in full compliance with one of the languages. MSVC++.NET for example has chosen to not support C99 (at least for the time being).
This is indeed a valid point which I should have mentioned in my reply as well...thanks for adding it.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|