The char16_t type and a C file

Hi,

I'm having trouble compiling a C file with the char16_t type, which should be a C11 compatible type. I do not have this problem when I compile a .ino project file with this type. I'm using VSCode with a automatically generated c_cpp_properties.json file. Within the file there are 2 properties defined: { "cStandard": "c11", "cppStandard": "c++11" } and I can also find the "__CHAR16_TYPE__=unsigned int" in the defines property array of the same file.

Lets give my an example. My test project consists of 2 files; a myproject.ino file and a test.c file in the same folder. The myproject.ino file contains

static char16_t arr[] = u"Καλημέρα";
static char16_t banana = u'🍌';

extern "C" char test(char16_t ch);

void setup()
{
  Serial.begin(9600);
}

void loop()
{
  Serial.print(arr[0]);
  Serial.print(test(banana));
}

The test.c file contains:

#include <Arduino.h>

char test(char16_t ch)
{
    return (char)ch & 0xff;
}

If I change the char16_t type to the uint16_t type, it compiles just fine.

There is no <uchar.h> header file in the arduino library to be found. I did vind the atomic_char16_t type in <stdatomic.h>

I'm not sure what to do next. To be honest I believe that C files are not compiled with the C11 standard but instead the C99 standard. But looking into the arduino build folder I found the following in the compile_commands.json.

[
 {
  "directory": "c:\\Users\\Jipinx\\Documents\\Arduino\\libraries\\protoduino",
  "arguments": [
   "C:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-g++",
   "-c",
   "-g",
   "-Os",
   "-w",
   "-std=gnu++11",
   "-fpermissive",
   "-fno-exceptions",
   "-ffunction-sections",
   "-fdata-sections",
   "-fno-threadsafe-statics",
   "-Wno-error=narrowing",
   "-MMD",
   "-flto",
   "-mmcu=atmega328p",
   "-DF_CPU=16000000L",
   "-DARDUINO=10607",
   "-DARDUINO_AVR_UNO",
   "-DARDUINO_ARCH_AVR",
   "-IC:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino",
   "-IC:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard",
   "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\myproject.cpp",
   "-o",
   "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\myproject.cpp.o"
  ],
  "file": "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\myproject.cpp"
 },
 {
  "directory": "c:\\Users\\Jipinx\\Documents\\Arduino\\libraries\\protoduino",
  "arguments": [
   "C:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\tools\\avr-gcc\\7.3.0-atmel3.6.1-arduino7/bin/avr-gcc",
   "-c",
   "-g",
   "-Os",
   "-w",
   "-std=gnu11",
   "-ffunction-sections",
   "-fdata-sections",
   "-MMD",
   "-flto",
   "-fno-fat-lto-objects",
   "-mmcu=atmega328p",
   "-DF_CPU=16000000L",
   "-DARDUINO=10607",
   "-DARDUINO_AVR_UNO",
   "-DARDUINO_ARCH_AVR",
   "-IC:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\cores\\arduino",
   "-IC:\\Users\\Jipinx\\AppData\\Local\\Arduino15\\packages\\arduino\\hardware\\avr\\1.8.6\\variants\\standard",
   "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\test.c",
   "-o",
   "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\test.c.o"
  ],
  "file": "C:\\Users\\Jipinx\\Documents\\Arduino\\build\\sketch\\test.c"
 }
]

I hope someone can help me with this, because i'm beginning to get bald...

Regards,

Jipinx.

Are you sure your C compiler is configured for C11?

.ino is essentially C++; not C

Thank you for your quick reply. I added the contents of the compile_commands.json file in my question above for completeness. I'm also aware that an .ino project file is basically a C++ file. However the char16_t is a native C11 type. see: char16_t - cppreference.com

I forgot to say that I am able to change the char16_t to wchar_t. The downside is that wchar_t is of variable length and doesn't have a fixed size defined by the C standard.

Also worth to mention is the fact that I can not define a string literal with UTF16 encoding or UCS2 encoding for that matter by using in the myproject.ino file a contruct like this:

static uint16_t arr[] = u"Καλημέρα"; // <-- doesn't work!!
static uint16_t banana = u'🍌'; // <-- works!!

which errors out with the following:

C:\Users\Jipinx\Documents\Arduino\libraries\protoduino\examples\myproject\myproject.ino:1:25: error: array must be initialized with a brace-enclosed initializer
static uint16_t arr[] = u"Καλημέρα"; // <-- doesn't work!!
^~~~~~~~~~~~~~~~~~~
Error during build: exit status 1

I hope this helps.

But is your C compiler configured for C11 ?

Is there a particular reason this needs to be a C file?
As suggested in the linked thread (and others) can you not just make it a C++ file?
ie, just rename from .c to .cpp

Idd rather not use cpp at all. which is my preference. I assume that you read the compile_commands.json I posted in my first post of this thread, which states: "-std=gnu11". I'm not sure how I should configure it otherwise...

To answer my own question, it appears that char16_t and char32_t are not supported as char types for C11. This is not the case for C++11 which does support these types. Its also good to know that these types appear to pack wide character strings as UTF16 and UTF32 respectively, which is not a fixed size character format like UCS2 and UCS4. Therefor it makes them less appealing and arguably less useful. The other character type wchar_t is supported by C11, but is not guaranteed to be of any predetermined size, and can change from platform to platform or compiler to compiler. Also, like char16_t and char32_t, the wchar_t type packs or UTF16 or UTF32, which is not really clear either from the specs.

Since this current character implementation is kind of useless for embedded devices, I will add proper conversion methods soon to the protoduino library at (GitHub - jklarenbeek/protoduino).

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.