0

I'm writing a C project and I want to test it using catch2 framework. But I'm having some odd behaviors with a function that returns a struct.

The C code is bellow:

stream_type.h

#ifndef STREAM_TYPE
#define STREAM_TYPE

#include <stdint.h>

#ifdef __cplusplus
extern "C"
{
#endif

typedef struct StreamType
{
    size_t offset;
    const size_t size;
} StreamType;

StreamType stream_type_make(size_t size);

#ifdef __cplusplus
}
#endif

#endif // STREAM_TYPE

stream_type.c

#include "stream/stream_type.h"

StreamType stream_type_make(size_t size)
{
    return (StreamType){.size = size, .offset = 0};
}

My catch2 test:

stream_type_test.cpp

#include "catch.hpp"

#include "stream/stream_type.h"

#include <iostream>

TEST_CASE("stream_type_make must creat StreamType correctly",
          "[stream_type_make]")
{
    StreamType stream_made = stream_type_make(35);

    std::printf("offset: %X \n size: %X\n\n", stream_made.offset, stream_made.size);
}

Ps.: The imported file "catch2.hpp" is the file distributed in the v2.13.8

The output after build is:

[1/1] Cleaning all built files...
Cleaning... 14 files.
[8/14] Building CXX object test\CMakeFiles\GALI_utils_test.dir\src\utils_test.cpp.obj
C:\Users\ggabr\Desktop\utils\include\stream/stream_type.h(18): warning C4190: 'stream_type_make' has C-linkage specified, but returns UDT 'StreamType' which is incompatible with C
C:\Users\ggabr\Desktop\utils\include\stream/stream_type.h(12): note: see declaration of 'StreamType'
[12/14] Building CXX object test\CMakeFiles\GALI_utils_test.dir\src\stream\stream_type_test.cpp.obj
C:\Users\ggabr\Desktop\utils\include\stream/stream_type.h(18): warning C4190: 'stream_type_make' has C-linkage specified, but returns UDT 'StreamType' which is incompatible with C
C:\Users\ggabr\Desktop\utils\include\stream/stream_type.h(12): note: see declaration of 'StreamType'
[14/14] Linking CXX executable test\GALI_utils_test.exe

The output after run executable is:

[1/1] cmd.exe /C "cd /D C:\Users\ggabr\Desktop\utils\build\win-dbg\test && C:\Users\ggabr\Desktop\utils\build\win-dbg\test\GALI_utils_test.exe"

offset: CCCCCCCC 
size: CCCCCCCC

===============================================================================
test cases: 1 | 1 passed
assertions: - none -

Ps.: If necessary I can add the cmake files to, but my executable test target has the "cxx_std_20" compile feature.

So, why this is happen? Why the the "stream_made" variable is not initialized as expected (size = 35, offset = 0)?

  • 2
    Are you using MSVC? It doesn't like `const` members here. – Barmar Jan 18 '22 at 20:13
  • See https://stackoverflow.com/questions/57431947/tales-from-the-msvc-extern-c?noredirect=1&lq=1 – Barmar Jan 18 '22 at 20:13
  • @Barmar Yes, I'm using MSVC version 19.29.30133 – Gabriel Lira Jan 18 '22 at 20:17
  • 3
    https://stackoverflow.com/search?q=warning+C4190+has+C-linkage+specified%2C+but+returns+UDT+which+is+incompatible+with+C -- you're not the first one to stumble across this problem. – Ulrich Eckhardt Jan 18 '22 at 20:17
  • 1
    The `%X` directives are not properly matched with the corresponding `size_t` arguments. `%zX` would be correct. Fixing that might or might not change the output. – John Bollinger Jan 18 '22 at 21:34
  • Ok, initially I tried only disable compiler warning but obviously only this doesn't worked and I was not realising the real reason that cause this behavior. @Barmar "@Ulrich Eckhardt" and "@John Bolinger" thanks for help. To really try to solve I realized that I only have two options with this compiler: remove const from struct or put the function into a Macro that agree with C and C++ syntax. How this function only creates an object I didn't see any problem in use a macro instead it. So I changed my function for: ```c #define stream_type_make(SIZE) {.offset = 0, .size = SIZE} ``` – Gabriel Lira Jan 19 '22 at 16:46

0 Answers0