I know programming in Java, but I'm reading "The C Programming Language", second edition. It says that to compile and run a program from the command line you have to do:
$ cc hello.c //assuming the name of the file is hello.c
./a.out
and hello world is printed. I tried that and worked fine.
Now, there is another example that prints a bunch of Celsius and Fahrenheit temperatures, so I created a file called TemperatureConverter.c with the given code. However, in the command line, when I ran:
$ cc TemperatureConverter.c
I got an error:
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
I don't know what this means. I tried double checking my syntax and it looks correct. I included the screenshot of the given code compared to the code I wrote, in case anybody notices a difference that may be causing the error:
#include <stdio.h>
main()
{
float fahr, celcius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
fahr = lower;
while (fahr <= upper) {
celcius = (5.0/9.0) * (fahr - 32.0);
printf("%3.0f %6.1f\n", fahr, celcius);
fahr = fahr + step;
}
}
I just ran your code in cygwin using the same command and it compiled/ran fine. I will say the same things others have mentioned.
main has the return type int.
it's parameters should be (void) or (int argc, **int argv).
You can have main() however this lets any parameters be passed into the main function.
Third the main function should end with return 0;
This indicates that the program exited correctly.
In the end it should look like this
#include <stdio.h>
int main(void)
{
float fahr, celcius;
int lower, upper, step;
lower = 0;
upper = 300;
step = 20;
fahr = lower;
while (fahr <= upper) {
celcius = (5.0/9.0) * (fahr - 32.0);
printf("%3.0f %6.1f\n", fahr, celcius);
fahr = fahr + step;
}
return 0;
}
There's absolutely nothing syntacticly wrong with your code. Though the modifications suggested by FrozenHawk are a good idea. I noticed the linker error talks about an undefined reference to main in function _start. I've never even heard of a function _start as the starting point in a c file; though that could be an internal, compiler specific, thing not strictly specified in the standards.
You should be absolutely sure you're trying to compile the correct file. Use cat on the same argument for extra assurance. Your code compiled just fine for me, as is, and with the commands you used on Debian. It seems unlikely, but this could be an issue with gcc. On my machine, no function called _start appears in any files in /usr/include/, which implies something lower level. You might consider uninstalling and reinstalling as a last resort.
Related
I've noticed a problem on some C code that I'm writing where when I multiply two long doubles I sometimes get lower than expected accuracy. I've isolated an example below, note that this is an mex file for use in matlab. Repeating exactly the same code in pure c results in the expected behaviour.
#include <mex.h>
#include <stdint.h>
typedef int32_t q0_31; // 32 bit signed fixed point number with 31 fractional bits
// conversion to long double from q0_31
long double q0_31_to_ldouble(q0_31 d) {
return d/2147483648.0L;
}
/* The gateway function */
void mexFunction( int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
{
mwSize nInputs = 0;
mwSize nOutputs = 0;
q0_31 b;
long double b_ld;
/* check for proper number of arguments */
if( nrhs!=nInputs )
mexErrMsgIdAndTxt("filter_interface:nrhs","wrong number of inputs!");
if( nlhs!=nOutputs )
mexErrMsgIdAndTxt("filter_interface:nlhs","wrong number of outputs!");
// random value for b
b = 0x81948b0e;
// convert to long double directly
b_ld = b/2147483648.0L;
mexPrintf("Inline calculation...\n");
mexPrintf("b_ld:\t%0.16LA\n",b_ld);
mexPrintf("b_ld^2:\t %0.16LA\n",b_ld*b_ld);
// repeat with sub function
b_ld = q0_31_to_ldouble(b);
mexPrintf("Exactly the same with sub function...\n");
mexPrintf("b_ld:\t%0.16LA\n",b_ld);
mexPrintf("b_ld^2:\t %0.16LA\n",b_ld*b_ld);
}
After compilation, this is the output I get from the code:
Inline calculation...
b_ld: -0XF.CD6E9E4000000000P-4
b_ld^2: 0XF.9B7D0E4BEE0D3100P-4
Exactly the same with sub function...
b_ld: -0XF.CD6E9E4000000000P-4
b_ld^2: 0XF.9B7D0E4BEE0D0000P-4
It is totally bizarre, the value returned by the function is exactly the same as the inline calculation. Yet when I square it I get a different result.
As I only get this behaviour in the mex and not when I compile the same code directly with gcc I thought it might be due to some strange compiler flag that matlab uses. But I have not been able to find anything.
Any ideas? Can anyone replicate?
MATLAB Version: 7.14.0.739 (R2012a)
gcc: 4.8.1-10ubuntu9
We've been interfacing with a library created from the Matlab Compiler. Our problem is related to an array returned from the library.
Once we're finished with the array, we'd like to free the memory, however, doing this causes occasional segmentation faults.
Here is the Matlab library (bugtest.m)::
function x = bugtest(y)
x = y.^2;
Here is the command we used to build it (creating libbugtest.so, and libbugtest.h)::
mcc -v -W lib:libbugtest -T link:lib bugtest.m
Here is our C test program (bug_destroyarray.c)::
#include <stdio.h>
#include <stdlib.h>
#include "mclmcrrt.h"
#include "libbugtest.h"
#define TESTS 15000
int main(int argc, char **argv)
{
const char *opts[] = {"-nojvm", "-singleCompThread"};
mclInitializeApplication(opts, 2);
libbugtestInitialize();
mxArray *output;
mxArray *input;
double *data;
bool result;
int count;
for (count = 0; count < TESTS; count++) {
input = mxCreateDoubleMatrix(4, 1, mxREAL);
data = mxGetPr(input); data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;
output = NULL;
result = mlfBugtest(1, &output, input);
if (result) {
/* HERE IS THE PROBLEMATIC LINE */
/*mxDestroyArray(output);*/
}
mxDestroyArray(input);
}
libbugtestTerminate();
mclTerminateApplication();
}
Here is how we compile the C program (creating bug_destroyarray)::
mbuild -v bug_destroyarray.c libbugtest.so
We believe that mxDestroyArray(output) is problematic.
We run the following to test crashing:
On each of the 32 cluster nodes.
Run bug_destroyarray.
Monitor output for segmentation faults.
Roughly 10% of the time there is a crash. If this is independent across nodes
then you might suppose it is crashing roughly 0.3% of the time.
When we take out that problematic line we are unable to cause it to crash.
However memory usage gradually increases when this line is not included.
From the research we've done, it seems we are not supposed to destroy the array returned, if not, how do we stop from leaking memory?
Thanks.
Okay, I know this is a little old now, but in case it helps clarify things for anyone passing by ...
Amro provides the most pertinent information, but to expand upon it, IF you don't call the mxDestroyArray function as things stand, then you WILL leak memory, because you've set output to NULL and so the mlf function won't try to call mxDestroyArray. The corollary of this is that if you've called mxDestroyArray AND then try to call the mlf function AND output is NOT NULL, then the mlf function WILL try to call mxDestroyArray on output. The question then is to what does output point? It's a bit of a dark corner what happens to output after passing it to mxDestroyArray. I'd say it's an unwarranted assumption that it's set to NULL; it's certainly not documented that mxDestroyArray sets its argument to NULL. Therefore, I suspect what is happening is that in between your call to mxDestroyArray and the code re-executing the mlf function, something else has been allocated the memory pointed to by output and so your mlf function tries to free memory belonging to something else. Voila, seg fault. And of course this will only happen if that memory has been reallocated. Sometimes you'll get lucky, sometimes not.
The golden rule is if you're calling mxDestroyArray yourself for something that is going to be re-used, set the pointer to NULL immediately afterwards. You only really need to destroy stuff at the end of your function anyway, because you can safely re-use output variables in mlf calls.
Guy
A few notes:
I don't see singleCompThread in the list of allowed options for mclInitializeApplication.
The recommended way to compile your C program is to dynamically link against the compiled library:
mbuild -v -I. bug_destroyarray.c -L. -lbugtest
At the top of your C program, just include the generated header file, it will include other headers in turn. From looking at the generated header, it has:
#pragma implementation "mclmcrrt.h"
#include "mclmcrrt.h"
I dont know the exact meaning of this pragma line, but maybe it matters with GCC compilers..
The fact that both mlx/mlf generated functions return booleans is undocumented. But looking at the header files, both signatures do indeed return a bool:
extern bool mlxBugtest(int nlhs, mxArray *plhs[], int nrhs, mxArray *prhs[]);
extern bool mlfBugtest(int nargout, mxArray** x, mxArray* y);
I tried your code and it works just fine with no segfaults. As I dont have access to a cluster of computers, my testing was only done on my local machine (WinXP with R2013a).
I had to remove both MCR initialization options for it to work (specifically the nojvm caused a runtime error). Below is the full code with slight modifications. It took around 10 seconds to run:
#include <stdio.h>
#include <stdlib.h>
#include "libbugtest.h"
#define TESTS 15000
int main()
{
mxArray *output, *input;
double *data;
int count;
bool result;
if( !mclInitializeApplication(NULL,0) ) {
fprintf(stderr, "Could not initialize the application.\n");
return EXIT_FAILURE;
}
if ( !libbugtestInitialize() ) {
fprintf(stderr, "Could not initialize the library.\n");
return EXIT_FAILURE;
}
for (count = 0; count < TESTS; count++) {
input = mxCreateDoubleMatrix(4, 1, mxREAL);
data = mxGetPr(input);
data[0] = 0.5; data[1] = 0.2; data[2] = 0.2; data[3] = 0.1;
output = NULL;
result = mlfBugtest(1, &output, input);
if (!result) {
fprintf(stderr, "call failed on count=%d\n", count);
return EXIT_FAILURE;
}
mxDestroyArray(output); output = NULL;
mxDestroyArray(input); input = NULL;
}
libbugtestTerminate();
mclTerminateApplication();
return EXIT_SUCCESS;
}
Also the compilation step is a bit different on Windows, since we statically link against the import lib (which inserts a stub to dynamically load the DLL on runtime):
mbuild -v -I. bug_destroyarray.c libbugtest.lib
Thanks for the detailed reply Amro.
We tried changing our compilation steps to the recommended ones, with no success.
The following fixed our seg-faulting problem:
Do not set output = NULL at each iteration, instead do it once outside of the loop.
Do not call mxDestroyArray(output) inside the loop, reference: here.
Our misunderstanding was that (it seems) you are supposed to reuse mxArray pointers which you pass to MATLAB functions. It makes things slightly cumbersome on our side as we need to be careful reusing this pointer.
However, memory is completely stable, and we've not had a crash since.
I have written a simple lex program to perform average of positive numbers , the program is compiling fine but i'm not able to get the expected output.I'm passing the input to the program from a file by giving filename as a commandline argument.The output of the lex program is blank showing no result , i'm a beginner in lex and any help would be appreciated . I have attached the code below. The code is written in redhat linux kernel version 2.4.
%{
#include <stdio.h>
#include <stdlib.h>
%}
%%
[0-9]+ return atoi(yytext);
%%
void main()
{
int val, total = 0, n = 0;
while ( (val = yylex()) > 0 ) {
total += val;
n++;
}
if (n > 0) printf(“ave = %d\n”, total/n);
}
The input file contains numbers 3,6 and 4 and the name of the file is passed as command line argument.
./a.out < input
Your program works for me. I'm a bit suspicious of yywrap missing, so you probably link with the -lfl (or something alike) option. This library contains a yywrap and a main. Even though I'm not able to reproduce what you see, I'm wary that maybe the main from libfl is used. I'm assuming you do get any newlines in the input file on the output. Different linkers have different ways of resolving multiple occurrences of the same symbol.
All in all I think you have to look for the problem in the way your program is built, because the specification seems ok. If you add int yywrap(void) { return 1; } after your main, then you can do without libfl, which is what I would advise any user of lex and gnu-flex.
The origin of this question is from here How to use "global static" variable in matlab function called in c.
I'm trying to encapsulate the "global variable" into an object. However I don't know how to export the matlab class to c++ using MATLAB Compiler (mcc)
To do this I just tried the standard command
Matlab Command
mcc -W cpplib:Vowel4 -T link:lib Vowel4.m
Matlab Script
classdef Vowel4
properties
x
y
end
methods
Vowel4
A
B
end
end
The generated lib is actually stand-alone functions rather than c++ class.
How can I compile classes in Matlab into c++ classes?
I've been searching for an answer but didn't find one.
Obviously the matlab command is not suitable for this scenario. However I cannot find any information on building Matlab classes into c++ classes.
========================== Edit ========================
The actual cpp code is as follows: #Alan
mclInitializeApplication(NULL, 0);
loadDataInitialize();
soundByCoefInitialize();
loadData();
mwArray F(4, 1, mxDOUBLE_CLASS);
float test[4];
for ( ;; ){
const Frame frame = controller.frame();
const FingerList fingers = frame.fingers();
if ( !fingers.empty() ){
for ( int i = 0; i < 4; i ++ ){
double v = fingers.count() > i ? (fingers[i].tipPosition().y / 50) - 2 : 0;
F(i+1,1) = v;
test[i] = v;
cout << v << ' ';
}
cout << endl;
soundByCoef(F);
}
}
Here the matlabA() corresponds to the loadData(), which loads the data, and soundByCoef(F) corresponds to the matlabB(), which do the job in the main loop.
As noted by Alan, I was only suggesting using handle class as a container for your global variables (with the benefit that such an object would be passed by reference). The created object is not intended to be directly manipulated by your C++ code (it will be stored in the generic mxArray/mwArray C/C++ struct).
As far as I know, you cannot directly compile classdef-style MATLAB classes into proper C++ classes when building shared libraries using the MATLAB Compiler. It only supports building regular functions. You could create functional interfaces to MATLAB class member methods, but that's a different story...
Perhaps a complete example would help illustrate the idea I had in mind. First lets define the code on the MATLAB side:
GlobalData.m
This is the handle class used to store the global vars.
classdef GlobalData < handle
%GLOBALDATA Handle class to encapsulate all global state data.
%
% Note that we are not taking advantage of any object-oriented programming
% concept in this code. This class acts only as a container for publicly
% accessible properties for the otherwise global variables.
%
% To manipulate these globals from C++, you should create the class API
% as normal MATLAB functions to be compiled and exposed as regular C
% functions by the shared library.
% For example: create(), get(), set(), ...
%
% The reason we use a handle-class instead of regular variables/structs
% is that handle-class objects get passed by reference.
%
properties
val
end
end
create_globals.m
A wrapper function that acts as a constructor to the above class
function globals = create_globals()
%CREATE_GLOBALS Instantiate and return global state
globals = GlobalData();
globals.val = 2;
end
fcn_add.m, fcn_times.m
MATLAB functions to be exposed as C++ functions
function out = fcn_add(globals, in)
% receives array, and return "input+val" (where val is global)
out = in + globals.val;
end
function out = fcn_times(globals, in)
% receives array, and return "input*val" (where val is global)
out = in .* globals.val;
end
With the above files stored in current directory, lets build the C++ shared library using the MATLAB Compiler:
>> mkdir out
>> mcc -W cpplib:libfoo -T link:lib -N -v -d ./out create_globals.m fcn_add.m fcn_times.m
You should expect the following generated files among others (I'm on a Windows machine):
./out/libfoo.h
./out/libfoo.dll
./out/libfoo.lib
Next, we could create a sample C++ program to test the library:
main.cpp
// Sample program that calls a C++ shared library created using
// the MATLAB Compiler.
#include <iostream>
using namespace std;
// include library header generated by MATLAB Compiler
#include "libfoo.h"
int run_main(int argc, char **argv)
{
// initialize MCR
if (!mclInitializeApplication(NULL,0)) {
cerr << "Failed to init MCR" << endl;
return -1;
}
// initialize our library
if( !libfooInitialize() ) {
cerr << "Failed to init library" << endl;
return -1;
}
try {
// create global variables
mwArray globals;
create_globals(1, globals);
// create input array
double data[] = {1,2,3,4,5,6,7,8,9};
mwArray in(3, 3, mxDOUBLE_CLASS, mxREAL);
in.SetData(data, 9);
// create output array, and call library functions
mwArray out;
fcn_add(1, out, globals, in);
cout << "Added matrix:\n" << out << endl;
fcn_times(1, out, globals, in);
cout << "Multiplied matrix:\n" << out << endl;
} catch (const mwException& e) {
cerr << e.what() << endl;
return -1;
} catch (...) {
cerr << "Unexpected error thrown" << endl;
return -1;
}
// destruct our library
libfooTerminate();
// shutdown MCR
mclTerminateApplication();
return 0;
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)run_main, 0, NULL);
}
Lets build the standalone program:
>> mbuild -I./out main.cpp ./out/libfoo.lib -outdir ./out
And finally run the executable:
>> cd out
>> !main
Added matrix:
3 6 9
4 7 10
5 8 11
Multiplied matrix:
2 8 14
4 10 16
6 12 18
HTH
Following on from the thread in the previous post, the suggestion wasn't to wrap your functions in a class, but rather to use a class to pass about the global variable which compiling leaves you unable to use.
classdef Foo < handle
properties
value
end
methods
function obj = Foo(value)
obj.value = value;
end
end
end
Note: the class Foo extends the handle class in order to make it pass by reference, rather than pass by value. See: the comparison between handle and value classes.
function foo = matlabA()
foo = new Foo(1);
end
function matlabB(foo)
foo.value
end
As far as I know, the matlab compiler doesn't compile the code as such, but rather packages it with a copy of the MATLAB Component Runtime and writes some wrapper functions to handle invoking said runtime on the code from c/c++.
I would recommend avoiding jumping back and forth between matlab and c/c++ too much; there is bound to be some overhead to converting the datatypes and invoking the MCR. All I really use it for is wrapping up a complex but self-contained matlab script (i.e.: doesn't need to interact with the c/c++ code mid way through said script) as a function, or packaging up code for deployment to environments which don't have a full copy of matlab.
As an interesting side note: if you are calling C++ from within Matlab, and that C++ code needs access to a global variable, things are much easier. You can simply do this by wrapping your C++ code into a mexFunction and compiling that. In the places you need to access a variable which is in the Matlab workspace, you can do so using the mexGetVariablePtr which will return a read-only pointer to the data. The variable you are accessing can be in either the global workspace, or that of the function which called your mexFunction.
With this approach I would suggest liberally comment the variable that you are getting in both the C++ and Matlab code, as the link between them may not be obvious from the Matlab side; you wouldn't want someone to come along later, edit the script and wonder why it had broken.
In this case it seems that the C++ side doesn't really need access to the data, so you could refactor it to have matlab do the calling by wrapping the "get current position of fingers" code into a mexFunction, then have matlab do the loop:
data = loadData();
while(~stop) {
position = getFingerPositionMex();
soundByCoef(position, data);
}
Assuming you don't modify the data within soundByCoef Matlab will use pass by reference, so there will be no copying of the large dataset.
I am more of a Matlab programmer, and have not used C in years! Now I have to write some code in C and have it called from Matlab via the mexFunction command. So far so good. But my code requires many function calls where both the argument and the return values are arrays. For this I am using pointer returns. But I have run into about a million difficulties, once one is fixed another is created.
example of the sort code is as follows (the actual code is massive)
#include "mex.h"
#include "math.h"
int Slength=95;
double innercfunction(double q,double y)
{
int i;
double X;
X=q*y;
}
double *c1function(double q,double Sim[])
{
double *F12=malloc(Slength);
int i;
double vdummy,qdummy;
qdummy=q;
for(i=0;i<Slength;i++)
{
vdummy=Sim[i];
F12[i]=innercfunction(qdummy,vdummy);
}
return F12;
}
void mexFunction(int nlhs, mxArray *prhs[],int nrhs,const mxArray *plhs[])
{
double *q=mxGetPr(prhs[0]);
double *Sim=mxGetPr(prhs[1]);
double *SS=c1function(q,Sim);
}
i save it as help_file.c and compile from THE MATLAB workspace as:
mex -g help_file.c
to which i get the following error:
help_file.c: In function ‘mexFunction’:
help_file.c:38: error: incompatible type for argument 1 of ‘c1function’
help_file.c:17: note: expected ‘double’ but argument is of type ‘double *’
i tried initially passing Sim[i] instead of vdummy, that did not work which is why I defined the dummy variable in the first place.
I imagine this is a trivial problem, but I would still appreciate peoples help on this.
The prototype of clfunction requires you to pass a scalar double as the first argument; you're passing a pointer-to-double q, hence the compiler error. Are you expecting prhs[0] to contain a scalar? If so, you could use q[0] to extract the value; or else, you could use mxGetScalar(prhs[0]) which returns a scalar-double ( http://www.mathworks.com/help/techdoc/apiref/mxgetscalar.html ).
However, I'm not sure that fixing that would make your mex file work as expected. I would suggest taking some time to read the mex examples here: http://www.mathworks.com/support/tech-notes/1600/1605.html
In particular, your current mex file isn't going to produce any output arguments since you aren't assigning to the left-hand side plhs.