VScode "expression must have a constant value" in c99 mode - c

What I'm trying to do:
I need to write integers into a 2d array. The length of the array is N*N. So I scanf to get the value of N from the user.
The C/C++ extension gives the "expression must have a constant value". But building it with gcc works perfectly fine
What I've tried:
C/C++ extension gives error on N in both arrays, "expression must have a constant value".
After some googling answers, I tried to set my compiler version in the extension to c99, since that is the version which supports variable length arrays. But it still give the same error. Tried using other newer c versions, the intellicense still gives the same error.
Code and settings:
tree.c:
#include <stdio.h>
#include <stdlib.h>
int main() {
int N, i, j;
scanf("%d", &N);
int min_tree[N][N];
int tree_walked[N];
}
c_cpp_properties.json:
{
"name": "TUF_Laptop",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/include",
"/usr/include",
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include",
"/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include-fixed",
"/usr/lib/gcc/x86_64-pc-linux-gnu"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "/usr/bin/gcc",
"intelliSenseMode": "linux-gcc-x64",
"compilerArgs": [
"-O3 -Wall -Wextra -std=c99"
],
"cStandard": "c99",
"cppStandard": "gnu++17",
"compileCommands": ""
}
Similar answers I found:
"expression must have a constant value" error in VS code for C

The IDE may be warning you of a potential programming error, since value N can be changed while mintree and treewalked are still in scope. You should be able to fix this with the following modification:
#include <stdio.h>
#include <stdlib.h>
int main() {
int N_scan, i, j;
scanf("%d", &N_scan);
const int N = N_scan;
int min_tree[N][N];
int tree_walked[N];
}
The value of N cannot be changed while min_tree and tree_walked are in scope.
There is a similar answer (for a C++ case) here:
https://stackoverflow.com/questions/9219712/c-array-expression-must-have-a-constant-value#:~:text=expression%20must%20have%20a%20constant%20value.%20When%20creating,declared%20const%3A%20doesn%27t%20even%20provide%20a%20variable%20name.

Just to add to the other answer, VS Code's intellisense defaults to MSVC as compiler. MSVC does not support the entirety of C99 including non-constant length arrays.
You can change the compiler used in VS Code's settings and set it to GCC which supports this feature.
In vs code, type "C/C++: Edit Configurations (UI)" (without the quotes) in the command palette (Ctrl + Shift + P) and edit the configuration. It will however create a .vscode/c_cpp_properties.json file in your folder. I don't think there is a way to set it globally other than copying this file to every .vscode folder.

Related

problem including gtk/gtk.h file not found windows 10 Visual Studio Code

There seems to be a problem floating around for some people using VSCode. I have confirmed the installation of GTK with the terminal window and everything went well.
I wrote a quick program in C to read an address and print it back. It compiles and runs (without the "#include <gtk.gtk.h">) creating the .exe file so I can confirm VScode is installed correctly.
#include <stdio.h>
#include <gtk/gtk.h>
int main()
{
int var = 20; /* variable declaration*/
int *ip; /* pointer variable declaration */
ip = &var; /* store the address of var in pointer variable */
printf("Address of var variable: %x\n", &var);
/* address stored in the pointer variable */
printf("Address stored in ip the pointer variable: %x\n", ip);
/* access the variable the *ip variable points to */
printf("Value of *ip variable: %d\n", *ip);
return 0;
}
When I add the #include <gtk/gtk.h> statement, I get the error that it cannot be found. >#include errors detected. Please update your includePath.<
I used the command "pkg-config --cflags --libs gtk+-3.0" in a terminal to create the path in c-cpp.json file
"configurations": [
{
"name": "Win32",
"includePath": [
"${workspaceFolder}/**",
"C:/msys64/mingw64/bin",
"C:/msys64/mingw64/include/gtk-3.0",
"C:/msys64/mingw64/include/pango-1.0",
"C:/msys64/mingw64/include",
"C:/msys64/mingw64/include/glib-2.0",
"C:/msys64/mingw64/lib/glib-2.0/include",
"C:/msys64/mingw64/include/harfbuzz",
"C:/msys64/mingw64/include/freetype2",
"C:/msys64/mingw64/include/libpng16",
"C:/msys64/mingw64/include/fribidi",
"C:/msys64/mingw64/include/cairo",
"C:/msys64/mingw64/include/lzo",
"C:/msys64/mingw64/include/pixman-1",
"C:/msys64/mingw64/include/gdk-pixbuf-2.0",
"C:/msys64/mingw64/include/atk-1.0",
"C:/msys64/mingw64/lib"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:/msys64/mingw64/bin/gcc.exe",
"cStandard": "gnu17",
"cppStandard": "gnu++17",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
the directory gtk is in the C:/msys64/mingw64/include/gtk-3.0 directory and the gtk.h file is in the gtk directory. Intellisense even prompted for the directory and file.

Visual Studio Code Include path error in C

It seems to be a simple problem but I can't find a solution to it.
I'm having a issues while including the header of a basic function I created.
main.c:2:10: fatal error: 'add.h' file not found
#include "add.h"
I made this code as simple a possible to highlight the main issue.
Here's my main code:
#include<stdio.h>
#include "add.h" //add.c function header
int main(int argc, char const *argv[])
{
int num1 = 5, num2 = 6;
add(num1, num2);
return 0;
}
add.c function code:
#include <stdio.h>
void add(int n1, int n2)
{
int sum = n1 + n2;
printf("%d + %d = %d\n", n1, n2, sum);
}
And the add.h
void add(int n1, int n2);
My c_cpp_properties.json file.
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/header"
],
"defines": [],
"macFrameworkPath": [
"/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
Project structuration:
Test_Header(folder)
source(folder)
main.c
add.c
header(folder)
add.h
I'm on Mac, my editor is Visual studio Code and I run the program with the run button provided by the "code runner" visual studio code extension.
I have a little light bubble on the top of my #include "add.h" saying "add to include path".
My guess is that it comes from the compiler, like he's not looking at the right place for the headers.
How can I change that (if that's what I need to do)?
Also, do changing it wouldn't change where he's supposed to find the built in c function library , like stdio ?
Or he can understand that he has a folder for the standard c function library and an other for user custom headers that should be located in the project directory ?
I've been 3 days on that issue, Couldn't find an answer on the web, or stuff that I couldn't understand. I could switch on an IDE but it will be like giving up.
I'm fairly new in the world of programmation as you can guess, so if you can keep it as simple as possible, it would be great :).
Thank you.

path: valid or not in `#include`?

Today I read this question Any rules about underscores in filenames in C/C++?,
and I found it very interesting that the standard seems to not allow what is usually seen in many libraries (I also do it in my personal library this way):
For example, in opencv we can see this:
// File: opencv/include/opencv2/opencv.hpp
#include "opencv2/opencv_modules.hpp"
But the standard says:
ยง 6.10.2 Source file inclusion
Semantics
5 The implementation shall provide unique mappings for sequences
consisting of one or more nondigits or digits (6.4.2.1) followed by a
period (.) and a single nondigit. The first character shall not be
a digit. The implementation may ignore distinctions of alphabetical
case and restrict the mapping to eight significant characters before
the period.
nondigit means letters (A-Z a-z) and underscore _.
It says absolutely nothing about / which would imply that it is forbidden to use a path, not to mention dots or hyphens in file names.
To test this first, I wrote a simple program with a source file test.c and a header file _1.2-3~a.hh in the same directory tst/:
// File: test.c
#include "./..//tst//./_1.2-3~a.hh"
int main(void)
{
char a [10] = "abcdefghi";
char b [5] = "qwert";
strncpy(b, a, 5 - 1);
printf("b: \"%c%c%c%c%c\"\n", b[0], b[1], b[2], b[3], b[4]);
/* printed: b: "abcdt" */
b[5 - 1] = '\0';
printf("b: \"%c%c%c%c%c\"\n", b[0], b[1], b[2], b[3], b[4]);
/* printed: b: "abcd" */
return 0;
}
// File: _1.2-3~a.hh
#include <stdio.h>
#include <string.h>
Which I compiled with this options: $ gcc -std=c11 -pedantic-errors test.c -o tst with no complain from the compiler (I have gcc (Debian 8.2.0-8) 8.2.0).
Is it really forbidden to use a relative path in an include?
Ah; the standard is really talking about the minimum character set of the filesystem supporting the C compiler.
Anything in the "" (or <> with some preprocessing first) is parsed as a string according to normal C rules and passed from there to the OS to do whatever it wants with it.
This leads to compiler errors on Windows when the programmer forgets to type \\ instead of '\' when writing a path into the header files. On modern Windows we can just use '/' and expect it to work but on older Windows or DOS it didn't.
For extra fun, try
#include "/dev/tty"
Really nice one. It wants you to type C code while compiling.
I'd would say it's not forbidden but not recommanded since it will not compile in some of cases there.
For example:
if you clone this directory into your root (so you'd have C:\test\).
if you try to run it in a virtual environment online, you may face issues.
Is it really forbidden to use a path in an include?
Not sure what you mean here: relative paths are commonly used, but using absolute path would be foolish.

#include <math.h> in Visual Studio 2012

This is a program I wrote :
#include "stdafx.h"
#include "math.h"
int main ()
{
int phi;
float c;
scanf_s("%d",&phi);
c=(pow(sin(phi)*cos(phi),-2))-(pow(tan(phi),2)+pow(tan(phi),-2));
if (c==2)
{
printf("C is 2,Don't Worry \n");
}
else
{
printf("Be Careful,C is not 2,How is this possible ?! \n");
}
}
The problem is Visual Studio won't recognize sin,cos,tan and pow.
what am I doing wrong ?
(as you see, the language is C!)
Despite that you haven't pointed out error message, most probable answer is that you need to explicitely tell your compiler, that you want to treat your code as C source file instead of C++ one. Visual Studio does not have project template for C console application "as is", but you may add source file manually. Just make sure that it has .c extension instead of .cpp.
I'm assuming you are actually compiling this as a C++ file as it should compile fine as a C file. You didn't specify the exact error message but in VS 2010 I get the error:
error C2668: 'sin' : ambiguous call to overloaded function
This is because your argument phi is an int and the compiler doesn't know which version of sin() to use. You can fix this by casting the integer to the desired type like:
int phi;
c = sin((float) phi);
or, simply change the type of phi to a float or a double.

C preprocessor redefine conflict dependent on include order

I just had a redefine conflict in the project I'm working on and while tracing down why it's not happening on all platforms (turned out to be to order of includes), I stumbled upon the following behavior which I cannot explain.
1. compiles without warnings
#define LIST_HEAD(a) { int a = 0; }
#include <sys/queue.h>
int main() {
return 0;
}
2. "macro redefined" warning
#include <sys/queue.h>
#define LIST_HEAD(a) { int a = 0; }
int main() {
return 0;
}
I would expect both cases to produce the warning, since there're no checks in <sys/queue.h> that would prevent a redefine.
So why does the first case produces no warning, while the second one does? What I'm missing here?
Btw: I get the same results on my Mac with clang and my Linux box with gcc.
By default, this warning is suppressed in system headers. The code in <sys/queue.h> is considered to come from a system header because sys/queue.h was found by searching a path marked as containing system headers.
So in (2) you see the warning because it is generated within your code, while in (1) the warning is generated within queue.h, and so is suppressed. Add -Wsystem-headers to your compilation options, and you'll see the warning in both cases.

Resources