labels as values in clang - c

I'm trying to implement "labels as values" (https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html) in a c program using clang 3.7 in Visual Studio 2015.
As a toy example I had the following code which causes the compiler to crash (internal error "fatal error C1001: An internal error has occurred in the compiler.
1> (compiler file 'c:\agent\build\cache\git\vctools\vctools\compiler\utc\src\p2\main.c', line 246)
1> To work around this problem, try simplifying or changing the program near the locations listed above.").
const void *array_jump[] = {&&S1,&&S2,&&S3,&&S3,&&S4};
S1:
goto *array_jump[3];
S2:
return 2;
S3:
return 3;
S4:
return 4;
If I move the array declaration to after all of the labels it works, until I include the array_jump variable in any of the statements.
S1:
//comment out and add "return 1;" and it will compile fine
goto *array_jump[3];
S2:
return 2;
S3:
return 3;
S4:
return 4;
const void *array_jump[] = {&&S1,&&S2,&&S3,&&S3,&&S4};
Can anyone provide an example like the one above that should work? Is this a problem with clang or with the "codegen" aspect for Visual Studio?
I think this bug is relevant but I'm not sure:
https://connect.microsoft.com/VisualStudio/feedback/details/2103400/crash-in-clang-c2-with-address-of-label-extension

The examples you build should work, I've just verified it using Apple LLVM version 7.0.2 (clang-700.1.81).
The mentioned bug reports seem to report this very same issue, until it's fixed, you can't do anything aside from trying to not use the extension.
While GNU C has some great extensions, if you want to write portable c code, try to avoid using any GNU C extension.

What you've linked to is a gnu-specific extension to the language. If you're not using a gnu compiler (I don't believe clang is), then it won't necessarily work. The documentation says to check for definition of the __GNUC__ name in the processor. Try adding this...
#ifndef __GNUC__
#error Not a GNU compiler, does not include GNU specific extensions
#endif

Related

VS Code C extension doesn't support GCC nested functions

I edit my C code with VS Code (1.17.0) with C/C++ Extension (1.12.0) that provides error checking. I compile my code with GCC compiler that supports nested functions. So if I write this
int foo(int x)
{
int bar(int x)
{
return x * 2;
}
return bar(x) + 1;
}
and compile it with gcc it works fine. However, the extension doesn't think so and red-squiggles the second curly brace with a "semicolon expected" error. The extension allows you to choose IntelliSense mode which I set to "windows-gcc-x64", however it doesn't seem to work. This issue exists since 2017. Is there a fix or a workaround?
C/C++ extension for VSCode does not support nested functions yet.
There is an issue open in their repo already, which you can track here.
... it's been there since 2017 though

Error C4576 in VS2015 enterprise

I have the error C4576 in Visual studio 2015 when I tried to compile the file: transcoding.c.
The source code of this file is here: transcoding.c
error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
The error arise at line 127 in this instruction:
enc_ctx->time_base = (AVRational) { 1, enc_ctx->sample_rate };
I used the source of ffmpeg in my project
https://www.ffmpeg.org/download.html
I searched around for a solution but I'm not able to correct the error
If someone have found something similar, please provide an idea
Despite what some other answers incorrectly claim, VS2015 compiler provides comprehensive support for C99 features, including the compound literal feature you are trying to use in that problematic line.
One possible explanation for the error message is that it the source file, despite being named as .c file, is being compiled as C++ file. The project settings might explicitly request C++ compiler for this file. In C++ this code is invalid.
Check your compilation settings to see if it by any chance includes a /TP ("compile as C++") switch.
Old question, but...
The solution is pretty simple:
AVRational tb;
tb.num = 1;
tb.den = enc_ctx->sample_rate;
enc_ctx->time_base = tb;
or
enc_ctx->time_base.num = 1;
enc_ctx->time_base.den = enc_ctx->sample_rate;
Remove the parenthesis around the type in the macro definition.
That should work.
enc_ctx->time_base = AVRational { 1, enc_ctx->sample_rate };
Looks like a question where the C and C++ tags make sense. You're trying to compile C99 code with a C++ compiler. That doesn't work.

Old gcc compiler on matlab

I am using MATLAB on the Linux MINT. I have a C program for which I want to used mex command as follows:
mex /home/.../binary.c -output binary_m
but I get the following error
Warning: You are using gcc version "4.8.1-10ubuntu9)". The version
currently supported with MEX is "4.4.6".
For a list of currently supported compilers see:
http://www.mathworks.com/support/compilers/current_release/
/home/.../binary.c:43:19: fatal error: binary.h: No such file or directory
#include "binary.h"
^
compilation terminated.
mex: compile of ' "/home/.../binary.c"' failed.
I think that I have to downgrade the gcc compiler on the MATLAB but I don't know how.
Any help is appreciate it.
Regards
This has nothing to do with the warning regarding the compiler version; don't pay attention to that, you will be fine. You might have had problems trying to compile c++11 sources, depending on your Matlab version, compiler version and mex command flags, but this is not your case.
Here is the problem: your C program binary.c contains an #include statement of the file binary.h which is not found by Matlab (although I trust you put it in the same directory than the C file?) because the directory that contains your C sources is not in the Matlab path.
To fix the problem, simply change directory to where binary.c is, and mex your file there. You can automate the process doing something like:
source_dir = '/home/.../';
current_dir = fileparts(mfilename('fullpath'));
cd source_dir;
% do something
cd current_dir;

Is `__value` a gcc extension, and if so, what does it do? Does it have a VC++ equivalent?

Title says it all.
I am trying to use some of the libraries from cygwin's gcc with visual studio's C++ compiler but the following code from C:\cygwin\usr\include\sys\_types.h does not compile:
#ifndef __mbstate_t_defined
/* Conversion state information. */
typedef struct
{
int __count;
union
{
wint_t __wch;
unsigned char __wchb[4];
} __value; /* Value so far. */
} _mbstate_t;
#endif
Build Output:
1>c:\cygwin\usr\include\sys\_types.h(74): error C4980: '__value' : use of this keyword requires /clr:oldSyntax command line option
1>c:\cygwin\usr\include\sys\_types.h(74): error C2059: syntax error : '__value'
Visual Studio seems to be interpreting this as some sort of CLR extension
Is __value a gcc extension, and if so, what does it do? Does it have a VC++ equivalent?
It's the other way around. It's a keyword in VC++ but not in gcc.
In gcc, it's just an identifier.
This link says
C/C++ Standards explicitly says that identifiers that contains double underscore are reserved:
ISO.IEC 14882:2003 C++ Standard, section 17.4.3.1.2 "Global names":
"Certain sets of names and function signatures are always reserved to the implementation:
-- Each name that contains a double uderscore (__) or begins with an underscore followed by an upper-case letter (2.11) is reserved to the implementation for any use. ..."
Since it looks like Visual Studio uses the __value keyword in Managed Extensions for C++, could you maybe just rename __value to something else (like __Value)?
[the MSDN link above also has a dicsussion whether this is a bug in unmanaged C, the Microsoft reply seems to be that this is "by design"]

Can I export the used code from a c program with many compiler flags?

I would like to condense our linux driver code in to only the code that runs on the current kernel. It has parts that are ignored by if statements all the way back to kernele 2.4.x
Have you ever heard of a way to compile the code to an output which will be the working code with out all the stuff ignored by the c compiler if else statements?
I am wondering if we can run make something or gcc something that will simply result in all the code that is used for that build.
So like if I had this .c file below, then after running the make command I should have just the code I need for the newest kernel.
example.c
static somefunction .... {
avar = 0;
#if (linux_ver >= 2.6.31)
some newer code
#elseif (linux_ver >= 2.4.24)
some older code
#else
original code
#endif
}
after extracting / condensing, example.c would simply read as below
static somefunction .... {
avar = 0;
some newer code
}
The tool you are after is sunifdef or (more recent) coan.
See also: Is there a C pre-processor which eliminates #ifdef blocks based on values defined or undefined?
That's what the preprocessor directives do already. Try running the code through gcc -E (but prepare for a lot of output, as all #includes will be inlined).

Resources