Link to home
Start Free TrialLog in
Avatar of jl66
jl66Flag for United States of America

asked on

How cl compiles the code an array wih variable size

Tried to use VC++ 2008 command line utility cl to compile the code that contains an array with variable size. A lot of errors were generated. In Linux all needs to do is to include the option -std=C99 when compiling.  Is there any workaround for it? Can any gurus shed some light to it? Thanks a lot.
Avatar of phoffric
phoffric

Doesn't seem likely based on my search. I once had vs2008, but lost it and could not find it again on reputable sites.


MSVC supports very little of C99 in C mode. The few things that it does (like '//' comments) are really extensions they've added to C90 mode that come from C++, which may happen to also be in C99. When compiling C code, MSVC treats '//' comments as an extension to C90, not that you're intermixing C90 code with C99 code.
https://stackoverflow.com/questions/2656080/ms-vs-2008-and-c99

Things that earlier versions already supported (I think since at least MSVC 7.1 / Visual Studio 2003):

// style comments.
long long type.
Flexible array members (Microsoft called them "unsized arrays").
Variadic macros (at least partially).
Things that are still missing:

Variable length arrays (optional in C11).
S
upport for the inline keyword (you can use __inline, but semantics might be slightly different).
Support for the restrict keyword (you might be able to use __restrict).
Type-generic math functions from tgmath.h.
_Complex type (optional in C11).
https://stackoverflow.com/questions/9610747/which-c99-features-are-available-in-the-ms-visual-studio-compiler/28118893
there is a batchfile named vcvars32.bat which should set all needed variables and macros. the batch file is located at

    \Program Files (x86)\Microsoft Visual Studio xx.0\VC\bin

replace xx by your VS version. probably  it is Visual Studio 9.0.  there is also a batchfile at VC folder named vcvarsall.bat which also could be used.


additionally you should check environment variables path, include, and lib which were evaluated by commandline build.

alternatively to using cl directly you might use devenv or msbuild directly for commandline build. the devenv.exe is in subfolder Common\IDE of your VS installation. type devenv.exe /? to get info about commandline builds.

Sara
What language (C, C++?) and version of that language are you targeting?

What do you mean by an array with variable size? Please clarify so we can be sure we're all talking about the same thing.

C99 has support for arrays that can be sized with non-compiletime variables. Earlier versions of C and C++ (any version) do not. As phoffic has alluded, Microsoft's support for C99 is incomplete. I refer you to a post by Herb Sutter (head of the C++ standards committee and guy in charge of Visual Studo development) for more details.

https://herbsutter.com/2012/05/03/reader-qa-what-about-vc-and-c99/

If you need full C99 support you can build code on Windows using GCC (just like on Linux). The Windows version of GCC can be found here:

https://gcc.gnu.org/install/binaries.html

Another option is to use LLVM:

https://llvm.org/docs/GettingStartedVS.html

There are also other compilers you could consider. Sadly, Microsoft's isn't one of them.
Tried to use VC++ 2008 command line utility cl to compile the code that contains an array with variable size.

vc++ is c++. cl.exe is the compiler and linker of vc++. commandline builds do not use the project defaults for standard libraries, include paths and executable paths defined in the project and solution file. instead, environment variables like include, lib and path are used. because of that include statements for STL (that comes with VS 2008) most likely would fail with cryptic error messages because of the templates if the 'include' environment variable wasn't properly set.

jl66, can you post the error messages you got?

Sara
Avatar of jl66

ASKER

Thanks a lot for everyone's inputs. here are the errors I encountered. All are from roughly one source, which is
---------
...
int matchVal(int arr[], int n, int r, int v)
{
// A temporary array to store all combination sums one by one
  int data[r];    
...
---------
I used Linux with -std=C99 to compile and run it without problem.

error C2057: expected constant expression
error C2466: cannot allocate an array of constant size 0
error C2133: 'data' : unknown size
error C2143: syntax error : missing ';' before 'type'
error C2143: syntax error : missing ';' before 'type'
error C2143: syntax error : missing ')' before 'type'
error C2143: syntax error : missing ';' before 'type'
error C2065: 'j' : undeclared identifier
warning C4552: '<' : operator has no effect; expected operator with side-effect
error C2065: 'j' : undeclared identifier
error C2059: syntax error : ')'
error C2146: syntax error : missing ';' before identifier 's'
error C2065: 'j' : undeclared identifier
error C2143: syntax error : missing ';' before 'type'
error C2143: syntax error : missing ';' before 'type'
error C2143: syntax error : missing ')' before 'type'
error C2143: syntax error : missing ';' before 'type'
error C2065: 'i' : undeclared identifier
error C2065: 'i' : undeclared identifier
error C2065: 'i' : undeclared identifier
As noted above, you can't build this because r isn't a compile time constant. Microsoft's compiler doesn't support C99. Put simply, you can't do that.

There are many other errors there, but those are probably related to this one issue; however, without being able to see all the code isn't only possible to conjecture.
Avatar of jl66

ASKER

If I ran it in Linux, I placed the option -std=C99 and the execution goes smooth. There must be some ways to workaround it.
Well, I've already give you the options, above. You either need to use a different compiler (because Microsoft's doesn't support C99) or modify your code. There are no other solutions to this I'm afraid. Neither ANSI C nor C++ support dynamically sized arrays.

>>  I placed the option -std=C99
This is telling GCC to build the code using the C99 standard, something Microsoft's compiler doesn't support. Again, there is no workaround to this. You need to use a different compiler (such as GCC for Windows) or change your code to be ANSI C (or C++) compatible.

The thing to remember is that Microsoft's compiler is a C++ compiler that just happens to support ANSI C (because C++ is based on ANSI C). C99 is a different beast and, as such, it's just not supported by Microsoft's compiler. It never has been and, according to Herb Sutter (chief developer of Microsoft's compiler), never will be.
use
if (r > 0)
{
      std::vector<int> dataarr(r); 
      int * data = &dataarr[0];

Open in new window


instead.

note, if r is less or equal 0 you would get issues even with C99 compliant compilers.

Sara
Note, you'll have to compile as C++ if you follow Sara's suggestion.
Avatar of jl66

ASKER

Sorry not to update it for a few days.
Yes. I followed Sara's instructions and tried to compiled the program. I got the same errors.
------------
make_seriesV3.c(25) : error C2143: syntax error : missing ';' before ':'
make_seriesV3.c(26) : error C2143: syntax error : missing ';' before 'type'
make_seriesV3.c(31) : error C2065: 'data' : undeclared identifier
make_seriesV3.c(31) : warning C4047: 'function' : 'int *' differs in levels of indirection from 'int'
make_seriesV3.c(31) : warning C4024: 'getAllCombinationSum' : different types for formal and actual parameter 2
make_seriesV3.c(46) : error C2143: syntax error : missing ';' before 'type'
make_seriesV3.c(46) : error C2143: syntax error : missing ';' before 'type'
make_seriesV3.c(46) : error C2143: syntax error : missing ')' before 'type'
make_seriesV3.c(46) : error C2143: syntax error : missing ';' before 'type'
--------------
25   std::vector<int> dataarr(r);
26    int * data = &dataarr[0];
--------------

Later I
Are you compiling it as C++?
Did you include the vector header?
Avatar of jl66

ASKER

evilrix--
Yes.
I installed the newer version of VS 16 and created a windown console project for my code.
I compiled it with Sara's post, but I got the running error. Since there are some loops and recursive function,  my computer was dead during debug running. I am checking them now, Please bear with me a bit before I close  this ticket.
It is always helpful if you post  the smallest file or program that identifies your problem. then we may be able to reproduce it ourselves and quickly give you a solution.
Avatar of jl66

ASKER

--phoffric     Here it is.

#include <stdio.h> 

#include <stdio.h> 
int fun1(int r) 
{
  if ( r < 1) return -1;
  int data[r]; 
  data[0] = 1; 
  return data[0];
} 

int main( )
{
  printf("result= %d ", fun1(1) );
}

Open in new window


The compile error is
test.c
test.c(6) : error C2143: syntax error : missing ';' before 'type'
test.c(7) : error C2065: 'data' : undeclared identifier
test.c(7) : error C2109: subscript requires array or pointer type
test.c(8) : error C2065: 'data' : undeclared identifier
test.c(8) : error C2109: subscript requires array or pointer type
test.c(8) : warning C4033: 'fun1' must return a value
>> int data[r];

You can't do this. The variable'r' MUST be a compile time constant. If you want to do this at runtime you need to use malloc/calloc and free. There is no workaround for this. It is defined as such in the ANSI C standard. C99 can do this, but Microsoft's compiler doesn't support C99. This is quite simply a case of "you can't do this".
try this:

#include <iostream>
#include <vector>

int fun1(int r)
{
  if ( r < 1) return -1;
  std::vector<int> dataarr(r);
  int * data = &dataarr[0];
  data[0] = 1;
  return data[0];  
  // coming here the array was deleted by the destructor of std::vector
}

int main( )
{
    std::cout << "result= " << fun1(1) << std::endl;
    return 1;   // set here a break point 
}

Open in new window


if your interface doesn't require a c array (pointer) you could do

int fun1(int r)
{
  if ( r < 1) return -1;
  std::vector<int> data(r, 1);    // here the array elements already were initialized
  return data[0];  
  // coming here the array was deleted by the destructor of std::vector
}

Open in new window


Sara
Avatar of jl66

ASKER

sarabande, I fully believe the provided code works. What kind of compiler did you use? Can you list it in a bit detail and how to compile it? Thanks a lot.
ASKER CERTIFIED SOLUTION
Avatar of sarabande
sarabande
Flag of Luxembourg image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jl66

ASKER

Thanks for everyone's effort.