ws2811_t: Initializing typedef struct from C library properly in C++ - zero

I am trying to use the C library from jgraff (https://github.com/jgarff/rpi_ws281x) in a C++ project. When using the library compiled examples the string works perfectly but within my C++ project the code doesn't compile.
First I was running the the same problem as described here:
Initializing typedef struct from C library properly in C++
I am still on my way to learn C++ but this struct is beyond my understanding and therefore I just copied the code over and get now the following errors.
error : braces around scalar initializer for type ‘int’
Then I stripped the initialization of the struct to the following:
ws2811_t ledstring =
{
nullptr,
TARGET_FREQ,
DMA,
GPIO_PIN, 0, LED_COUNT, 255
};
And now I am getting the following error:
error: invalid conversion from ‘int’ to ‘const rpi_hw_t*’
Please can anybody advice what's wrong?

Using the -fpermissive option with g++ treats this error as warning and the code compiles well.

Related

Why calling a function from shorthand function pointers array initialization doesn't compile?

I have the following code in my project:
printf("Please select one of the tests: ");
int n;
scanf("%d", &n);
(void (* [])()) {test1, test2, test3, test4}[n - 1]();
For me, this code compiles and works as indented. But my professor said that this doesn't compile for her.
I write code compliant with the C23 standard and my compiler is Apple Clang v13.0.0. But about my professor, all I know is that she uses the MSVC compiler; I have no information on either the compiler version or the standard she marks the code with.
I tried changing the C standard to C99 and it still worked, so I think this has to be a compiler issue. I don't have a Windows machine to play around with MSVC and test whether the problem is the anonymous array initialization, the subscript operator immediately after it, the call operator after the entire thing, or something else entirely.
Now, of course I know that I can declare an array of function pointers first, and then assign every element, or just use a switch for this purpose. I also know that this is a kind of "clever code" that may not be welcome in actual projects maintained by more people, but this is my code, created for educational purposes only. Also, my professor likes this kind of "clever tricks" as extreme examples of what can you do with the language. What I do like to know is what could be the reason this code does not compile with MSVC. Is that syntax some compiler-specific language extension or is it just Microsoft which, as always, is not keeping up with support for all language features?
Your teacher is probably compiling your code as C++.
With dummy functions added, if this code is placed in a .c file and compiled with MSVC 2015, it compiles fine. If the file has a .cpp extension, it generates the following errors:
x1.cpp(13): error C3260: ')': skipping unexpected token(s) before lambda body
x1.cpp(13): error C2143: syntax error: missing ';' before '}'
x1.cpp(13): warning C4550: expression evaluates to a function which is missing an argument list
x1.cpp(13): error C2676: binary '[': 'main::<lambda_8caaf9f5b122025ad6cda2ca258a66a7>' does not define this operator or a conversion to a type acceptable to the predefined operator
x1.cpp(13): error C2143: syntax error: missing ')' before ';'
x1.cpp(13): error C2059: syntax error: ';'
So it thinks your compound literal is a lambda function. Compound literals are a C-only construct, so unless your C++ compiler supports them as an extension it won't work.
Have your teacher compile your code as C by putting it in a file with a .c extension.
Alternately, don't use a compound literal. Create the array first, then index it and call the function.
void (*f[])() = {test1, test2, test3, test4};
f[n - 1]();

AZURE Cloud integration

I am working on the Azure iot cloud integration, i successfully build my SDK, i am trying compiling with my application, it is giving dependency errors and getting error like given below,
../../inc/azure_c_shared_utility/crt_abstractions.h:58:23: error: two or more data types in declaration specifiers
typedef unsigned char _Bool;
../../inc/azure_c_shared_utility/crt_abstractions.h:58:1: warning: useless type name in empty declaration [enabled by default]
typedef unsigned char _Bool;
../../inc/azure_c_shared_utility/crt_abstractions.h:125:2: error: #error unknown (or C89) compiler, provide ISNAN with the same meaning as isnan in C99 standard
#error unknown (or C89) compiler, provide ISNAN with the same meaning as isnan in C99 standard
Are you still blocked?
Try adding these lines to your Makefile to see if it works:
-DCMAKE_C_STANDARD=## \
-DCMAKE_CXX_STANDARD=## \
where ## are the standards for C and C++ (for example, -DCMAKE_C_STANDARD=99 will make the program be compiled against C99 standards).
Please see similar issue addressed here for reference.

C code with a union member name the same as its type name

I am currently working on some microcontroller code in C, and one of the third-party libraries I am using has some structs and unions defined in the following manner:
typedef struct
{
...members of struct...
} somename;
typedef struct
{
...members of struct...
} somename2;
typedef union
{
somename somename;
somename2 somename2;
} anothername;
The code compiles in Atmel Studio 7 (not sure what underlying compiler it's using), but it fails to compile in the Arduino IDE (which is using some version of gcc/g++ I believe).
Is the above code valid C? Or is it valid C++? Or valid either/neither? It seems strange to me that the authors of this code would give the members of this union a variable name that is identical to the type name which happens to be a struct they defined just above in the file.
Anyway, the Arduino compiler is throwing errors when it reaches this code, so I'm trying to figure out whether it's valid code and how to make the Arduino compiler like it. Any suggestions? Thanks!
Ir is compiling by default as C++ so you need to add -xc command-line option.
As far as I know C++ does not allow the same names for types and objects.

Get the current working directory in C on windows

For some bizarre reason, when I try to use the function get_current_dir_name with MinGW GCC compiler,
I get this result on linkage:
undefined reference to `get_current_dir_name'
collect2.exe: error: ld returned 1 exit status
But, I get this only when using the function like this
printf("%i", get_current_dir_name());
or this
printf("%s", get_current_dir_name());
When I try to do
printf(get_current_dir_name());
I get this, which makes no sense, because the function returns a char *, according to docs:
tester.c: In function 'main':
tester.c:16:2: warning: passing argument 1 of 'printf' makes pointer from integer without a cast [enabled by default]
printf(get_current_dir_name());
^
In file included from tester.c:1:0:
c:\mingw\include\stdio.h:294:37: note: expected 'const char *' but argument is of type 'int'
_CRTIMP int __cdecl __MINGW_NOTHROW printf (const char*, ...);
Google seem to really dislike talking about C, because I can find how to get the workdir on almost any existing language, except C. The only thing that pops up are some docs, which describe 3 functions: getcwd, getwd, and get_current_dir_name. I really want to use the get_current_dir_name one because of it's cleanness.
How do I deal with this? Is this a minGW bug? Or am I missing something?
You apparently failed to include any header that contains a declaration of get_current_dir_name(). Thus, the compiler will assume a return value of int, which is not a valid first argument for printf() (you should increase the warning levels so you'll get an error instead of just a warning).
Furthermore, linking fails, so you also do not link against a library that implements the function, which is expected: get_current_dir_name() is a GNU extension and not part of the C standard library.
On Windows, you need to use the equivalent functionality provided by the Windows API, ie GetCurrentDirectory(), declared in windows.h.

Compiler Error C2143 when using a struct

I'm compiling a simple .c in visual c++ with Compile as C Code (/TC)
and i get this compiler error
error C2143: syntax error : missing ';' before 'type'
on a line that calls for a simple struct
struct foo test;
same goes for using the typedef of the struct.
error C2275: 'FOO' : illegal use of this type as an expression
I forgot that in C you have to declare all your variables before any code.
Did you accidentally omit a semicolon on a previous line? If the previous line is an #include, you might have to look elsewhere for the missing semicolon.
Edit: If the rest of your code is valid C++, then there probably isn't enough information to determine what the problem is. Perhaps you could post your code to a pastebin so we can see the whole thing.
Ideally, in the process of making it smaller to post, it will suddenly start working and you'll then have discovered the problem!
Because you've already made a typedef for the struct (because you used the 's1' version), you should write:
foo test;
rather than
struct foo test;
That will work in both C and C++
How is your structure type defined? There are two ways to do it:
// This will define a typedef for S1, in both C and in C++
typedef struct {
int data;
int text;
} S1;
// This will define a typedef for S2 ONLY in C++, will create error in C.
struct S2 {
int data;
int text;
};
C2143 basically says that the compiler got a token that it thinks is illegal in the current context. One of the implications of this error is that the actual problem may exist before the line that triggers the compiler error. As Greg said I think we need to see more of your code to diagnose this problem.
I'm also not sure why you think the fact that this is valid C++ code is helpful when attempting to figure out why it doesn't compile as C? C++ is (largely) a superset of C so there's any number of reasons why valid C++ code might not be syntactically correct C code, not least that C++ treats structs as classes!

Resources