Pass by reference in C99 - pass-by-reference

I just read this:
In C++ (and C99), we can pass by
reference, which offers the same
performance as a pointer-pass.
So I tried this simple code:
#include <stdio.h>
void blabla(int& x){
x = 5;
}
int main(){
int y = 3;
printf("y = %d\n", y);
blabla(y);
printf("y = %d\n", y);
}
The output was:
gcc test.c -o test -std=c99
test.c:3:16: error: expected ';', ',' or ')' before '&' token
test.c: In function 'main':
test.c:10:2: warning: implicit declaration of function 'blabla'
Now I'm confused. Is pass by referenced indeed supported by C99?

That page is wrong. There are no "references" in C (even in C99).
In C, when you want to pass "by reference," you fake reference semantics using a pointer.

Related

External Functions: Alternative Method to use .dll from a C-script

This is a companion question to External Functions: Reference headers in C-script to compiled dll.
That stack overflow question is using a Modelica external function call to a c-script. That c-script then uses c-functions contained within a .dll. Below is the initial preferred method I had attempted and a working attempt that I do not prefer.
Initial Attempt:
The following code would not work. My assumption was since I loaded the .dll Library libgsl in Modelica I could then simply use headers in the C-script to use function calls from that .dll. However, the dslog.txt file indicated that it couldn't recognize gsl_sf_bessel_j0. Apparently, the C-script doesn't know anything about the libgsl.dll that I specified in Modelica.
Modelica Function:
function chirp
input Modelica.SIunits.AngularVelocity w_start;
input Modelica.SIunits.AngularVelocity w_end;
input Real A;
input Real M;
input Real t;
output Real u "output signal";
external "C" u=chirp(w_start,w_end,A,M,t)
annotation(Library="libgsl", Include="#include \"chirp.c\"");
end chirp;
C-Script:
#include <gsl/gsl_sf_bessel.h>
double chirp2(double w1, double w2, double A, double M, double time)
{
double res;
double y;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
y = gsl_sf_bessel_j0(res);
return y;
}
Working Attempt:
In order to use a .dll in an external function call using a C-script I found it necessary to independently load the library using the LoadLibrary command.
Is this method really necessary? This is much more complicated that my initial attempt I hoped would work where I was thinking Modelica contained the necessary "know-how" to load the .dll.
Bonus: It appears there exists a way to send error messages back to Modelica. void ModelicaVFormatError(const char* string, va_list). Know of a reference example of its usage so I can replace the printf statements which don't seem to send anything back to Modelica?
Modelica Function:
function chirp
input Modelica.SIunits.AngularVelocity w_start;
input Modelica.SIunits.AngularVelocity w_end;
input Real A;
input Real M;
input Real t;
input String fileName= Modelica.Utilities.Files.loadResource("modelica://ExternalFuncTest/Resources/Library/libgsl.dll") "Full file name for GSL library";
output Real u "output signal";
external "C" u=chirp(w_start,w_end,A,M,t)
annotation(Include="#include \"chirp.c\""); // <-- Removed Library reference
end chirp;
C-Script:
#include <windows.h>
#include <stdio.h>
typedef double (__cdecl *BESSEL)(const double);
double chirp3(double w1, double w2, double A, double M, double time, const char* fileName)
{
HINSTANCE hinstLib;
BESSEL bessel_J0;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(fileName);
// If the handle is valid, try to get the function address.
double res;
double y = 0;
res=A*cos(w1*time+(w2-w1)*time*time/(2*M));
if (hinstLib != NULL)
{
bessel_J0 = (BESSEL) GetProcAddress(hinstLib, "gsl_sf_bessel_j0");
// If the function address is valid, call the function.
if (NULL != bessel_J0)
{
fRunTimeLinkSuccess = TRUE;
printf("Success loading library method.\n"); //<-- Alternative to send message back to Modelica log file?
y = bessel_J0(res);
} else
{
printf("Failed to load library\n"); //<-- Alternative to send message back to Modelica log file?
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
return y;
}

Can't compile an example program from The C Programming Language

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.

MATLAB, mex files, Fortran, warnings and errors

I'm not quite seeing the issue I'm having, and I've tried suggestions I've seen in other forum posts. I am trying to write a (fortran) mex file, per request of my boss. However, I was getting warnings when passing a matrix to my computational routine. If I ignored the warning, my MATLAB shut down. So now I'm trying a simpler program, an inner product. However, I am still getting the warning: "Expected a procedure at (1)" where (1) is at 'call innerProd(x,y,c)' underneath the x. I'm not sure what that means... I've included my code.
#include "fintrf.h"
C======================================================================
#if 0
C
C innerProd.F
C .F file needs to be preprocessed to generate .for equivalent
C
#endif
C
C innerProd.F
C calculates the inner product
C This is a MEX file for MATLAB.
C Copyright 1984-2011 The MathWorks, Inc.
C $Revision: 1.12.2.9 $
C======================================================================
C Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer:: plhs(*), prhs(*)
integer:: nlhs, nrhs
C Function declarations:
mwPointer:: mxCreateDoubleMatrix, mxGetPr,mxGetM, mxGetData
integer:: mxIsNumeric
C Pointers to input/output mxArrays:
mwPointer:: x_ptr, y_ptr, c_ptr
C Array information:
mwSize:: m
C Arguments for computational routine:
real*8:: x,y,c
C----------------------------------------------------------------------
C Check for proper number of arguments.
if (nrhs .ne. 2) then
call mexErrMsgTxt('Error.')
elseif (nlhs .ne. 1) then
call mexErrMsgTxt('One output required.')
endif
C Check to see if inputs are numeric.
if (mxIsNumeric(prhs(1)) .ne. 1 ) then
call mexErrMsgTxt('Input # 1 is not a numeric array.')
elseif (mxIsNumeric(prhs(2)) .ne. 1) then
call mexErrMsgTxt('Input #2 is not a numeric array.')
endif
C Find dimensions of mxArrays
m=mxGetM(prhs(1))
C create Fortran arrays from the input arguments
x_ptr=mxGetData(prhs(1))
call mxCopyPtrToReal8(x_ptr,x,m)
y_ptr= mxGetData(prhs(2))
call mxCopyPtrToReal8(y_ptr,y,m)
C create matrix for the return argument
plhs(1) =mxCreateDoubleMatrix(1,1,0)
c_ptr= mxGetPr(plhs(1))
C Call the computational subroutine.
call innerProd(x,y,c)
C Load the output into a MATLAB array.
call mxCopyReal8ToPtr(c, c_ptr, 1)
return
end subroutine mexFunction
C----------------------------------------------------------------------
C Computational routine
subroutine innerProd(x,y,c)
implicit none
real*8:: x,y,temp,c
integer:: i,m
do i=1,m
temp=temp+x(i)*y(i)
end do
c = temp
return
end subroutine innerProd
I'm just learning this for the first time, and I would appreciate any suggestions. Even if it is where to look for solutions. I've looked through MATLAB mex Fortran aids online. There isn't any help there. I can't get the function to run, so I can't use print statements which is a good way to debug. I think mex has a print function, I will try to get that to work.
Thank you!
The main problem is that you haven't anywhere declared the arguments of innerProd as arrays. That holds for the actual arguments x and y in the subroutine mexFunction and the dummy arguments x and y in innerProd itself.
So, in innerProd the expression x(i) isn't referencing the i-th element of the real*8 array x, but the real*8 result of the function x with argument i. As the x you've passed isn't a function (procedure), this is an error.
There are ways to solve this, but all involve declaring the dummy arguments as arrays. Which brings up another point.
You have in innerProd
integer:: i,m
do i=1,m
temp=temp+x(i)*y(i)
end do
where m is not defined. Crucially, from mexfunction you're expecting the compiler to know that m is the size of the arrays x and y: this isn't true. m is a variable local to innerProd. Instead you may want to pass it as an argument to the subroutine and use that to dimension the arrays:
subroutine innerProd(x,y,c,m)
implicit none
integer :: m
real*8:: x(m),y(m),temp,c
...
end subroutine
[You could, of course, use assumed-shape arrays (and the SIZE intrinsic), but that's an additional complication requiring more substantial changes.] You also need to think about how to declare arrays appropriately in mexfunction, noting that the call to mxCopyPtrToReal8 also requires an array argument.
I couldn't get the Fortran code to work for innerProd, but I did get C code to work. I recommend, if you are having issues with Fortran, to use C. It seems that Matlab is more flexible when it comes to mex files and C. Here is the code:
#include "mex.h"
/*
* innerProd.c
*
*Computational function that takes the inner product of two vectors.
*
*Mex-file for MATLAB.
*/
void innerProd(double *x, double *y,double *c,int m){
double temp;
int i;
for(i=0; i < m; i++){
temp = temp + x[i]*y[i];
}
*c=temp;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
double *x, *y, *c;
size_t m;
/*check for proper number of arguments.*/
if(nrhs != 2){
mexErrMsgIdAndTxt("MATLAB:innerProd:invalidNumInputs","Two input required.");
}
/*The input must be a noncomplex double vector.*/
m = mxGetM(prhs[0]);
if(!mxIsDouble(prhs[0]) || mxIsComplex(prhs[0]) || m==1){
mexErrMsgIdAndTxt("MATLAB:innerProd:inputNotRealDouble","Input must be noncomplex double vector");
}
/*create return argument */
plhs[0] = mxCreateDoubleMatrix(1,1,0);
c=mxGetPr(plhs[0]);
/*Assign pointers to each input and output. */
x = mxGetPr(prhs[0]);
y=mxGetPr(prhs[1]);
/*call subroutine*/
innerProd(x,y,c,m);
}
I will still take suggestions on the Fortran code above, though. I'd like to know how to get it to work. Thanks!

Why I get a syntax error when using typedef in verilog?

I don not know what is wrong here. I use a modelsim SE 6.5b. Then when I use "typedef" I get a syntax error.
`timescale 1ns/10ps
// Type define a struct
typedef struct {
byte a;
reg b;
shortint unsigned c;
} myStruct;
module typedef_data ();
// Full typedef here
typedef integer myinteger;
// Typedef declaration without type
typedef myinteger;
// Typedef used here
myinteger a = 10;
myStruct object = '{10,0,100};
initial begin
$display ("a = %d", a);
$display ("Displaying object");
$display ("a = %b b = %b c = %h", object.a, object.b, object.c);
#1 $finish;
end
typedef is a SystemVerilog keyword, not Verilog.
To enable SystemVerilog on Modelsim you need to add the -sv compile option and/or rename the file to with a .sv extension.
Your code works fine on Modelsim 10.1d. See example on EDA Playground (I had to add an endmodule but it's otherwise unmodified).
I'd suggest checking your compile flags to ensure you're enabling support for SystemVerilog during compilation.

error messages when writing Mex files, problem with array output from functions?

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.