-2

Is there a way to type cast structure member during its initiation, for instance:

struct abc {
    char k;
};
 
int main()
{
  struct abc data[] = {.k= 'TI'};
}

Above wouldn't work since k is of type char, is there way to type caste this member k (to int) during its assignment to 'TI' ?

JRose
  • 1,382
  • 2
  • 5
  • 18
Milan
  • 1,447
  • 5
  • 19
  • 27
  • What do you mean by *"type cast structure member*"? The member will always have a static type, what are you trying to achieve? – UnholySheep Aug 24 '22 at 15:13
  • I don't get it. Do you want to change the type during runtime? This is not possible. Data types are determined during compilation. – the busybee Aug 24 '22 at 15:13
  • 2
    What's `'TI'` supposed to be, a multi-byte character? Why would you want to assign that to an int? – Lundin Aug 24 '22 at 15:14
  • @Lundin, yes 'TI' is multi-byte char, and if I assign it to char then it wouldn't work, so I was thinking if member K which of type char can be type caste to int to store this multibyte value. – Milan Aug 24 '22 at 15:16
  • Wouldn't you rather want a `wchar_t` or an array of bytes? – Lundin Aug 24 '22 at 15:19
  • If you want `k` be to an `int`, you need to define the structure in that way. – the busybee Aug 24 '22 at 15:20
  • What are you actually trying to do? What is the underlying problem? – klutt Aug 24 '22 at 15:24
  • Unclear. What value to do you want to assign to `k`? – ikegami Aug 24 '22 at 15:29

4 Answers4

2

You don't need a cast here.

struct abc {
    char k;
};
 
int main()
{
  struct abc data[] = {.k= 'TI'};
}

Your object data is an array of struct abc. The initializer is for a single object of type struct abc.

If you want data to be a 1-element array, you can do this:

  struct abc data[] = {{.k= 'TI'}};

or, if you want to be more explicit:

   struct abc data[] = {[0] = {.k = 'TI'}};

That's valid code, but it's likely to trigger a warning. 'TI' is a multi-character constant, an odd feature of C that in my experience is used by accident more often than it's used deliberately. Its value is implementation-defined, and it's of type int.

Using gcc on my system, its value is 21577, or 0x5449, which happens to be ('T' << 8) + 'I'. Since data[0].k is a single byte, it can't hold that value. There's an implicit conversion from int to char that determines the value that will be stored (in this case, on my system, 73, which happens to be 'I').

A cast (not a "type cast") converts a value from one type to another. It doesn't change the type of an object. k is of type char, and that's not going to change unless you modify its declaration. Maybe you want to have struct abc { int k; };?

I can't help more without knowing what you're trying to do. Why are you using a multi-character constant? Why is k of type char?

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
0

No matter what you do to the value, it doesn't change the fact that the field cannot store that much information. You will need to change the type of k.

ikegami
  • 367,544
  • 15
  • 269
  • 518
0

"...I was thinking if member K which of type char can be type caste to int ..."

As mentioned in comments, struct members are static and cannot be cast.
But given your willingness to cast (even though that will not work) why not start with a type that naturally accommodates multi-byte characters, i.e. wchar_t ?

If this is acceptable for your work, then when working with multi-byte char in C, you can do the following:

#include <wchar.h>

struct abc {
    wchar_t k[2];//or k[3] depending on k will be used as a C string.
};
...
//inside function somewhere:
//assignment can be done as follows:
struct abc buf = {.k[0] = L'T', .k[1] = L'I'};
// Or:
struct abc buf = {.k = L"TI"};//Note, no null terminator, so not C string

Note: regarding 2nd method, by definition, L"TI" contains three characters, T, I and \0. If k is to be used as a string, k must be defined with space for the null terminator: wchar_t k[3];.
(See examples here.)

This results in the following:

enter image description here

(where 84 and 73 are the ASCII values for T and I respectively.)

Note: compiled using GNU GCC, set to follow C99 rules

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • ryyker, is this part of C++ only ? – Milan Aug 24 '22 at 16:02
  • @Milan - No, compiled its C using GNU GCC, set to follow C99 rules, but note the edit. Each multi-byte char needs its own space, so the struct member needed to be an array to accommodate `'TI'` – ryyker Aug 25 '22 at 14:08
0
  1. 'TI' is wrong you probably mean string "TI"
  2. If typecast mean see the sting "TI" as integer you need to use union - it is called type punning.
typedef union 
{
    char k[2]; //I do not want to store null terminating character
    short int x;
}union_t;

int main(void)
{
    union_t u = {.k = "TI"};

    printf("u.k[0]=%c (0x%x), u.k[1]=%c (0x%x) u.x = %hd (0x%hx)\n", u.k[0], u.k[0], u.k[1], u.k[1], u.x, u.x);
}

https://godbolt.org/z/EhbKG5qnW

ryyker
  • 22,849
  • 3
  • 43
  • 87
0___________
  • 60,014
  • 4
  • 34
  • 74