3

I have been generating a C function from Matlab Coder environnement in order to implement it in an other software called MAX/MSP. I'm trying to make sense of it, thanks to my poor level in C programming, and there is some syntax elements I can't understand: the use of unsigned values like 0U or 1U to pass arrays.

The next example doesn't do anything. Pasting the entire code wouldn't help much, unless you think so.

void function1(const double A[49], double B[50])
{
  function2( (double *)&A[0U] );
}

static void function2(const double A[])
{

}

While doing some math, Matlab wrote something like:

b = 2;
f[1U] += b;

I don't understand the use of unsigned value either...

Thanks a lot!

Passer By
  • 19,325
  • 6
  • 49
  • 96
Vic Tor
  • 85
  • 1
  • 4
  • The reason for spamming the C++ tag? And we are not an "explain the code" site. If you want to understand C, read a good C book. – too honest for this site Jul 05 '17 at 14:53
  • 2
    @Olaf: if you are having a bad day, take some time off SO ;-) – chqrlie Jul 05 '17 at 14:58
  • The literal `0` has the same value as `0U`, but differs in type -- the former has type `int`, whereas the latter has type `unsigned int`. Since the value is the same, however, the type difference does not matter to the value's use as an array index. That is, `A[0U]` is equivalent to `A[0]` and `f[1U]` is equivalent to `f[1]`. MATLAB's code generator is just a little quirky. – John Bollinger Jul 05 '17 at 14:59
  • 1
    @chqrlie: I have a fine day. It is just those people not reading rules or even taking the [tour] which shows up during final registration and asking obvious questions explained in every beginner's book. – too honest for this site Jul 05 '17 at 15:03
  • 1
    @Olaf: the OP seems to know the meaning of the `U` suffix, he wonders why the code generator uses it, and frankly, so do I. – chqrlie Jul 05 '17 at 15:06
  • @chqrlie: Learning C would help. `size_t` is the type which is guaranteed to hold all valid array indexes. And surprisingly, it is … unsigned. Both are explained in these paper-thingies (now also in electronic form). – too honest for this site Jul 05 '17 at 15:10
  • 1
    Thanks @JohnBollinger for the answer, that the information I needed! – Vic Tor Jul 05 '17 at 15:48
  • @chqrlie The automated code of `void function1(const double A[49], double B[50]) { function2( (double *)&A[0U] ); }` seems inconsistent. If a `u` is append like `0U`, I'd expect `49U` and `50U` too. – chux - Reinstate Monica Jul 05 '17 at 16:26
  • @chux: You are correct, but I'd be surprised if that was the only error. Also for a declarator the type might not be that relevant like for the index-operator/addition. – too honest for this site Jul 05 '17 at 16:52

2 Answers2

2

The U suffix is obviously not necessary here. It can be useful to force unsigned arithmetics in certain situations, with surprising side effects:

if (-1 < 1U) {
    printf("surprise!\n");
}

In some rare occasions, it is necessary to avoid some type changes. On many current architectures, the following comparisons hold and the type of 2147483648 is different from that of 2147483648U is more than just signedness:

For example, on 32-bit linux and 32- and 64-bit windows:

sizeof(2147483648) == sizeof(long long)  // 8 bytes
sizeof(2147483648U) == sizeof(unsigned)  // 4 bytes

On many embedded systems with 16-bit ints:

sizeof(2147483648) == sizeof(long long)       // 8 bytes
sizeof(2147483648U) == sizeof(unsigned long)  // 4 bytes
sizeof(32768) == sizeof(long)                 // 4 bytes
sizeof(32768U) == sizeof(unsigned int)        // 2 bytes

Depending on implementation details, array index values can exceed the range of both type int and type unsigned, and pointer offset values can be even larger. Just specifying U is no guarantee of anything.

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • `sizeof(2147483648) == sizeof(long) sizeof(2147483648U) == sizeof(unsigned)` - none of this is guaranteed. And they are often wrong. – too honest for this site Jul 05 '17 at 15:07
  • @Olaf: you are correct, neither of these are guaranteed, I amended my answer, but they are often true. – chqrlie Jul 05 '17 at 15:14
  • Not really. For WIndows it is wrong and for all CPUs with `int` less than 32 bits which is the vast majority of systems. – too honest for this site Jul 05 '17 at 15:27
  • @Olaf: you are cranky, but correct. I amended the answer again. In terms of numbers of systems, I agree they are probably more systems out there with small ints, but in terms of numbers of programmers, there are probably more people programming for 32 and 64 bit systems than embedded targets. – chqrlie Jul 05 '17 at 15:55
  • Thanks for the answer and the little examples, that answered my questions! – Vic Tor Jul 05 '17 at 16:03
  • @chqrlie: Considering the number of different devices with embedded CPUs and Windows systems, I disagree. It **might** be different if we add programming languages like JavaScript and Java, but not for C. And as I wrote: For Windows, it is also not correct (for POSIX32 it is also wrong, btw.). – too honest for this site Jul 05 '17 at 16:12
  • @Olaf: is my last edit still incorrect for the targets specified? – chqrlie Jul 05 '17 at 16:14
  • @chqrlie: Unrelated; about the just deleted post you answered: We have at least one troll here. Sorry, I will not tell more, as he reads comments. – too honest for this site Jul 05 '17 at 16:15
  • You shouid add systems with 17, 18, etc bit `int`, too;-) Point is: what you write is completely unnecessary and not related to the question. Remember we are not a tutoring site; it should be just question->answer, no decoration. If you feel you have to "blow up" the text like that, I'm likely correct the question is not suitable for this site. – too honest for this site Jul 05 '17 at 16:19
2

For a[n], array indexes are always non-negative values, from 0 to n-1. Appending a u to a decimal constant poses no problem for indexing an array, yet does offer a benefit: it insures that the value is of minimal type width and of some unsigned type.

Automated generation of a fixed index like with Matlab benefits by using a u suffix.


Consider small and large values on a 32-bit unsigned/int/long/size_t system

aweeu[0u];           // `0u` is 32-bit `unsigned`.
aweenou[0];          // `0` is 32-bit `int`.
abigu[3000000000u];  // `3000000000u` is a 32-bit `unsigned`.
abignou[3000000000]; // `3000000000` is a 64-bit `long long`.

Is this of value? Perhaps. Some compiles make look at the value first and see that all above are in range of size_t and not complain. Others may complain about an index of type long long or possible even int. By appending the u, such rare complaints do not occur.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256