1

I'm having trouble working with size_t* and uint32_t*

I have a program that has something like

int main ()
{
  size_t out_length;
  .
  .
  .
  func_1(param_1, ..., &out_length); 
  out_length > some_numberl;
}

func_1(param_1, ... , size_t *length)
{
 .
 .
 .
   *length = 0; 
 .
 .
   *length = to_some_unsigned_number;
}

As it is calling func_1(); in main works fine, but now I have to call func_1(); inside another function that looks like this

   func_2(param_1, ...,uint32_t* output_length)
   {
     
   }

so the program looks like this now

int main ()
{
      size_t out_length;
      .
      .
      .
      func_2(param_1, ..., &out_length); 
      out_length > some_number;
}

func_2(param_1, ...,uint32_t* output_length)
{
    func_1(param_1, ... ,output_length);
    
     //stuff
}

func_1(param_1, ... , size_t *length)
{
     .
     .
     .
       *length = 0; 
     .
     .
       *length = to_some_unsigned_number;
}

so my question is how to appropriately obtain the value of output_length. I currently read 0s.

I'll appreciate if someone could point me to the right direction.

IrAM
  • 1,720
  • 5
  • 18
PolarBear
  • 41
  • 7

1 Answers1

4

You cannot store the size_t value returned by f1 directly into the uint32_t variable pointed to by the f2 argument, since the types are different, and the sizes can be different, too. Instead, use an intermediate local in f2, which also gives a chance to test for out of range conditions. Same goes for the uint32_t value returned by f2 to main, just in the opposite direction.

#include <stdlib.h>
#include <stdint.h>

void func_1(size_t* length)
{
    *length = 42;
}

void func_2(uint32_t* output_length)
{
    size_t length;
    func_1(&length);
    if(length > UINT32_MAX) exit(1); // out of range
    *output_length = (uint32_t)length;
}

int main()
{
    size_t out_length;
    uint32_t f2_length;
    func_2(&f2_length);
    out_length = f2_length;
}
dxiv
  • 16,984
  • 2
  • 27
  • 49
  • I get that. Also, I knew about those `_MAX` constants, but their usage in ensuring overflow like `if (length > UINT32_MAX)`, makes more sense, I learned it! +1 – Rohan Bari Feb 02 '21 at 06:42
  • 2
    @RohanBari Actually, those constants are marked as *optional* by the standard, so strictly speaking that line should have been inside an `#ifdef UINT32_MAX` block. However, implementations would normally have those constants defined. – dxiv Feb 02 '21 at 06:46
  • I thought of suggesting typecast to and from `uint32_t` and `size_t`, but your approach is safe in case of size difference, you can add a print though in case of `if(length > UINT32_MAX)` – IrAM Feb 02 '21 at 12:38
  • 1
    thank you. that worked and I also understood why. I appreciate it. – PolarBear Feb 02 '21 at 14:38
  • @IrAM It may be tempting to cast, but it can be dangerous. In this case, where there are actually two intermediate steps, one is sure to fail when `size_t` and `uint32_t` are not the same size, – dxiv Feb 02 '21 at 15:09