Where's g++'s VLA extension? - c++

My question is related to this thread.
Here is the code
#include <stdio.h>
int main(int argc, char *argv[printf("Hello, world!\n")]) {}
I accidently saved it as a *.cpp file and tried to compile it with g++. But I got an error and a warning.
error: expected ',' or '...' before 'argv'
warning: second argument of 'int main(int, char*)' should be 'char **
'
I know the above code is not Standard C++ [size of an array must be a constant expression in C++] but
I always thought g++ supports Varible Length Array as an extension. Where am I wrong?
P.S : The above code gets compiled with CLang++
C:\Users\SUPER USER\Desktop>type check.cpp
#include <stdio.h>
int main(int argc, char *argv[printf("Hello, world!\n")]) {}
C:\Users\SUPER USER\Desktop>clang++ check.cpp
C:\Users\SUPER USER\Desktop>

g++ allows (again, as an extension) VLAs. I think it just doesn't allow them in parameter lists. This compiles in g++ 4.4.1.
#include <stdio.h>
int main(int argc, char *argv[])
{
char *array[printf("Hello, world!\n")];
}

Related

std::byte is not member of 'std'

I'm trying to learn new features/gimmicks of c++17, but then I got to std::byte and for some unknown reason I can't seem to be able to compile even most basic "hello world" type program with the type.
entire program:
#include <cstddef>
int main(int argc, char* argv[])
{
std::byte byte;
return 0;
}
compilation command:
g++ ./main.cpp
But the output is always:
./main.cpp: In function ‘int main(int, char**)’:
./main.cpp:4:10: error: ‘byte’ is not a member of ‘std’
std::byte byte;
I work on Ubuntu 18.04 with gcc 7.4.0. I have checked "/usr/include/c++/7.4.0/" and header file cstddef is there and byte seems to be defined.
I have also tried to use clang:
clang++ ./main.cpp
But the result was same. At this point I can only think that cstddef is corrupted/bugged. Are there any solutions to this?
As πάντα ῥεῖ pointed out in comment I was missing c++17 compile flag. Right compilation command:
g++ -std=c++17 ./main.cpp
If you use clang 5.0 (even with -std=c++17 flag) the same error occur.
In that case, to solve this you need to upgrade to clang 6.
A temporay and quick workaround is possible (but not recommanded since it plays with std namespace), it could be something like:
#if defined(__clang__) && __cplusplus >= 201703L && __clang_major__ < 6
// This is a minimal workaround for clang 5.0 with missing std::byte type
namespace std {
enum class byte : unsigned char {};
}
#endif

[[maybe_unused]] attribute not working

I am trying to ignore the unused parameter warning using the new c++17 attribute [[maybe_unused]], as below.
int main([[maybe_unused]] int argc, char** argv)
{
//...
}
But I still get warning: unused parameter ‘argc’ [-Wunused-parameter] with the following additional warning.
warning: ‘maybe_unused’ attribute directive ignored [-Wattributes]
I'm using g++ (GCC) 7.2.0 with cmake-3.11.3. My compiler flags are as follows.
-std=c++17 -Wall -pedantic -Wextra -Weffc++
I remember using this attribute successfully before, but I have no idea why this is not working now. Could someone show what I am doing wrong here?
You can suppress warning about unused variable this way:
int main(int /* argc */, char** argv)
{
//...
}
or using following trick:
int main(int argc, char** argv)
{
(void)argc;
//...
}
In this case this code will work for earlier versions of C++ standard and even for pure C.

Proper array type for execvp

I'm having difficulty figuring out exactly how to use execvp in C++. I'm not having any issues getting my code to work, but I'm specifically trying to figure out how to do it in a way that doesn't make the compiler complain.
I have looked at various questions on Stack Overflow and other resources, but I have been unable to find a solution that results in zero warnings from the compiler.
Consider the following C++ program, which prints its own source code:
#include <unistd.h>
int main(int argc, char *argv[])
{
char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
(I know that the return 0 should never be reached; I'm not so concerned with error handling in this question.)
When I compile it, the compiler emits two warnings:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:6:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[0] = "/bin/cat";
^~~~~~~~~~
exec.cpp:7:15: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
args[1] = __FILE__;
^~~~~~~~
The compiled program successfully prints the source file. However, I'd really like to get the program to compile without any warnings. Since the compiler doesn't like that the string literals are being assigned to a pointer of type char* (not const char*), I suppose it would make sense to mark args as an array of const char* pointers. Consider this version of the program:
#include <unistd.h>
int main(int argc, char *argv[])
{
const char *args[3];
args[0] = "/bin/cat";
args[1] = __FILE__;
args[2] = NULL;
execvp(args[0], args);
return 0;
}
I would think that this program should compile and run with no warnings or errors, but the compiler does emit an error:
$ g++ -Wall exec.cpp
exec.cpp: In function ‘int main(int, char**)’:
exec.cpp:10:25: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
execvp(args[0], args);
^
In file included from exec.cpp:1:0:
/usr/include/unistd.h:581:12: note: initializing argument 2 of ‘int execvp(const char*, char* const*)’
extern int execvp (const char *__file, char *const __argv[])
^~~~~~
I also tried declaring args as char const *args[3], but the compiler emits the same error. The only way I am able to get it to compile with no warnings is by casting args in the call to execvp:
const char *args[3];
...
execvp(args[0], (char* const*)args);
This version compiles without warnings and runs successfully. However, I prefer to avoid casting when I can, because it makes it harder for me to reason about the type conversions going on.
Are one of the two working ways that I have shown above the best way to create an argument array to pass to execvp, or is there a better way that is clear and does not result in the compiler complaining?
I am using two different compilers - g++ 6.2.0 for native compilation on Ubuntu x86_64, and g++ 4.5.3 for cross compilation to an ARM platform.
Edit:
I do not believe that my question is a duplicate of this question. I understand the different effects of using const in different ways with respect to a char* variable. I am specifically asking which type is conventionally used for execvp calls, which is not answered by the linked question.

Algorithm header llrint, llround compiler error

I'm learning C++ and I'm at the point of using the <algorithm> header and I get this compiler error even with an empty project:
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1108:11: error: '::llrint' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1109:11: error: '::llrintf' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1110:11: error: '::llrintl' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1112:11: error: '::llround' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1113:11: error: '::llroundf' has not been declared
/Users/italrolando/hpc-gcc47/bin/../lib/gcc/x86_64-apple-darwin11.4.0/4.7.1/../../../../include/c++/4.7.1/cmath:1114:11: error: '::llroundl' has not been declared
make: *** [algorithm.o] Error 1
Here is the code:
#include <iostream>
#include <algorithm>
using namespace std;
int main( int argc, char ** argv ){
return 0;
}
I'm using Eclipse with GCC 4.7.1 compiler and it's quite strange since the course I'm following is using Eclipse with Gcc 4.7 and it works.
Thanks

Can't build sigqueue example with gcc but g++ is ok?

I have a strange build problem.
I have a simple test program that sends a sigqueue to another process.
This little code example builds and runs when I build it as a c++ program (compiled with g++)
but when I compile it as a c program (with gcc) I get a error that he can't find the sigval struct.
The short example:
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
int main(int argc, char *argv[])
{
sigval value;
value.sival_int = 123;
sigqueue(0,SIGUSR1, value);
}
Please note that I replaced the pid with 0 to simplify this question.
And if I compile with gcc I get this:
$> gcc sigusr1_mini.c
sigusr1_mini.c: In function ‘main’:
sigusr1_mini.c:9: error: ‘sigval’ undeclared (first use in this function)
sigusr1_mini.c:9: error: (Each undeclared identifier is reported only once
sigusr1_mini.c:9: error: for each function it appears in.)
sigusr1_mini.c:9: error: expected ‘;’ before ‘value’
sigusr1_mini.c:10: error: ‘value’ undeclared (first use in this function)
What am I missing here, why can't he find the sigval struct?
And why can g++ find it?
Thanks
Johan
In C, struct and union tags do not introduce names that can be used on their own like they do in C++. You must spell it out:
union sigval value;
How is sigval defined in h-file? C compiler may require full definition, for example:
union sigval value;