Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
pseudorandom name
May 6, 2007

ExcessBLarg! posted:

Unfortunately any sufficiently-developed object system in C ends up relying on non-standards compliant behavior to implement inheritance.

Which behaviors are you talking about here?

Adbot
ADBOT LOVES YOU

ExcessBLarg!
Sep 1, 2001

pseudorandom name posted:

Which behaviors are you talking about here?
The big one is when data inheritance is implemented as a "base class" struct embedded in a "derived class" struct. Usually there will be a set of functions (of "virtual method" style) that take a pointer to the "base class" struct, but the function itself needs to access members of the "derived class".

There's a few ways to do it. Making the "base class" be the first element is probably the most portable. Where it's not the first element, one has to use offsetof to locate the start of the container struct. Since offsetof is part of C90 it should be safe to use so long as the compiler does (and should) implement it. The non-portability comes in that some variants of the macro place a fictitious instance of a struct at address 0, for the purpose of determining the address offset of a struct member.

The best way I've seen to achieve this effect is Linux's container_of macro. It differs from most implementations by using GCC's typeof operator (which is non-standard) and pointer assignment to perform type checking as best it can.

In short, there's ways of doing it that are reasonably standard-compliant but eschew type checking, and vice-versa. It's not a huge deal, but the fact that there isn't a type-safe standards-compliant version of container_of is one of there reasons why OOP in C is somewhat dicey and ad-hoc.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Doesn't C++ have a way to implement template methods only for certain template parameter matchups?

i.e. I'm trying to port a some old linear algebra types and make various aspects of it generic, but some things have implementations that are specific to particular row/column counts (i.e. fast inversions, cross product, etc.)

I'm trying this:
code:
template<class _Tfloat, LargeInt _Trows, LargeInt _Tcols>
class Mat
{
    ...
    Mat<_Tfloat, _Tcols, _Trows> Inverse() const;
    ...
};
... but it says that it can't match the definition when I try this:
code:
template<class _Tfloat>
inline Mat<_Tfloat, 3, 3> Mat<_Tfloat, 3, 3>::Inverse() const
{
   ...

OneEightHundred fucked around with this message at 02:28 on Mar 4, 2013

tractor fanatic
Sep 9, 2005

Pillbug
No. You have to specialize the entire class. You might want to consider doing it with template functions instead, which you can specialize.

edit: or you can use CRTP to make some mixins.

tractor fanatic fucked around with this message at 02:32 on Mar 4, 2013

Tetraptous
Nov 11, 2004

Dynamic instability during transition.
Speaking of which, I've got a 12K LOC numerical program I've written in C99 and as it grows in scope, it's becoming a bit more difficult to manage despite my best efforts to organize things into logical data structures and files. I'm starting to think it might be worthwhile to transition the program to C++ as I make further improvements, especially as there are a number of useful C++ numerical libraries which have been developed recently. I haven't worked with C++ much; any recommendations for where I should start, both in terms of my education and in terms of porting the code?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
It's pretty straightforward. The first thing to do is to just turn all your source files into C++ files and make sure everything still builds and runs. Once you've done that, it's mostly a matter of cleaning things up. Look at all of your types and start trying to improve encapsulation. Try to split out useful functions that work on on a single object. Functions that create a single object should probably become constructors (or at least static "factory" methods). Functions that destroy a single object should probably become destructors. Functions that clone an existing object should become copy constructors. Other functions that really just work on a single object probably ought to become instance methods on it. Try to make fields private if you can. Introduce getters and setters when it makes sense to. Use new and delete instead of malloc and free. And so on.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

tractor fanatic posted:

No. You have to specialize the entire class. You might want to consider doing it with template functions instead, which you can specialize.

edit: or you can use CRTP to make some mixins.
I decided to work around it by using static functions that do basically the same thing and are called by the instance method, but the overloads only match if they're called using a type that supports them.

code:
template<class _Tfloat, LargeInt _Trows, LargeInt _Tcols>
class Mat
{
private:
    static Mat<_Tfloat, 3, 3> Inverse(const Mat<_Tfloat, 3, 3> &self);
public:
    inline Mat<_Tfloat, _Tcols, _Trows> Inverse() const
    {
        return Inverse(*this);
    }
};
:effort:

The language not supporting it in instance methods seems kind of weird.

tractor fanatic
Sep 9, 2005

Pillbug
Oh if you only wanted to enable a function for a certain specialization you can use boost::enable_if. If you don't want to include boost you can make your own using SFINAE. It looks hacky as hell but it prevents a 4x4 matrix from having an inverse function. Or at the very least, add a static_assert to your current inverse method so that it's clear why there's a failure when you try to call inverse on a 4x4 matrix.

xgalaxy
Jan 27, 2004
i write code
enable_if is part of the standard library now.
If you have that luxury.

That Turkey Story
Mar 30, 2003

tractor fanatic posted:

Oh if you only wanted to enable a function for a certain specialization you can use boost::enable_if. If you don't want to include boost you can make your own using SFINAE. It looks hacky as hell but it prevents a 4x4 matrix from having an inverse function. Or at the very least, add a static_assert to your current inverse method so that it's clear why there's a failure when you try to call inverse on a 4x4 matrix.

enable_if is also in the C++11 standard as std::enable_if (it's equivalent to enable_if_c in boost).

Tetraptous
Nov 11, 2004

Dynamic instability during transition.

rjmccall posted:

It's pretty straightforward. :words: And so on.

Sounds like a plan!

Vanadium
Jan 8, 2005

ExcessBLarg! posted:

The big one is when data inheritance is implemented as a "base class" struct embedded in a "derived class" struct. Usually there will be a set of functions (of "virtual method" style) that take a pointer to the "base class" struct, but the function itself needs to access members of the "derived class".

There's a few ways to do it. Making the "base class" be the first element is probably the most portable. Where it's not the first element, one has to use offsetof to locate the start of the container struct. Since offsetof is part of C90 it should be safe to use so long as the compiler does (and should) implement it.

So you run into undefined behavior when you roll your own OOP in C, and you pick the non-obvious strategy of putting the base-class struct somewhere at the end (or do multiple inheritance I guess), and roll your own offsetof instead of using the one that comes with your implementation? That seems kinda managable, I dunno.

Zomodok
Dec 9, 2004

by Y Kant Ozma Post
I've been looking at this all night and just really need an extra set of eyes to help me out here.

I'm doing infix to postfix conversion and my output for the postfix isn't showing operators.

code:
for(int i = 0; i < input.length(); i++ )
{
     if(input[i] == '(')
     {
     	stack1.push(input[i]);
     }
     else if(input[i] == ')')
     {
     	while((stack1.stacktop() != '(') &&
	      (stack1.stacktop() != NULL))
        {
     	    output += stack1.stacktop();
     	    stack1.pop();
     	}
     }
     else if(isOperator(input[i]))
     {
	while(isOperator(stack1.stacktop()) && 
	      precedence(stack1.stacktop(), input[i]) &&
	   	         stack1.stacktop() != NULL)
	{
  	     output += stack1.stacktop();
	     stack1.pop();
	}
	
             stack1.push(input[i]);
     } 			
			
     else if(isdigit(input[i]))
     {
	output += input[i];
     }
}
Tell me where I've hosed up. I'll post the header and class file if I have to but I really think something isn't going right up there. the isOperator is nothing but a bool switch case returning true if any of +-*/^& are passed and precedence really just determines uh...precedence.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
What exactly is output? That += may not be doing what you think it's doing.

In general, learning how to use the debugger and stepping through your program really helps with figuring out this sort of thing.

Zomodok
Dec 9, 2004

by Y Kant Ozma Post

Jabor posted:

What exactly is output? That += may not be doing what you think it's doing.

In general, learning how to use the debugger and stepping through your program really helps with figuring out this sort of thing.

It's a string variable but the += should still add additional characters to it right? I have it initialized as "" and it still takes the numerical values and stores them/displays them but not the operators of + - / or *

I'll step through it after I wake up though :shobon:

edit;

After taking a shower and not looking at it I realized I had the break for my isOperator function commented out for some reason and now it works perfectly fine :suicide: I'm sorry

Zomodok fucked around with this message at 15:01 on Mar 4, 2013

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
How can I prevent a line of code from being optimized out no matter what type of build or platform?

Like when I really need a breakpoint on a specific line in an optimized build, for debugging:
code:
if ( some_debug_condition )
{
	int x=4; // this line is here solely so I can place a breakpoint
}

Gazpacho
Jun 18, 2004

by Fluffdaddy
Slippery Tilde
Test a volatile variable or call a function that does.
C++ code:
volatile bool b = false;
while(b);

b0lt
Apr 29, 2005

baby puzzle posted:

How can I prevent a line of code from being optimized out no matter what type of build or platform?

Like when I really need a breakpoint on a specific line in an optimized build, for debugging:
code:
if ( some_debug_condition )
{
	int x=4; // this line is here solely so I can place a breakpoint
}

Alternatively, generate the interrupt yourself.

code:
if ( some_debug_condition )
{
    asm("int $0x3");
}

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
Alternatively, you can figure out how to set conditional breakpoints and sidestep the issue entirely.

Rottbott
Jul 27, 2006
DMC
Conditional breakpoints won't necessarily work in an optimised build.

nielsm
Jun 1, 2009



b0lt posted:

Alternatively, generate the interrupt yourself.

code:
if ( some_debug_condition )
{
    asm("int $0x3");
}

This, but check if your compiler doesn't have an intrinsic function to generate the breakpoint. I know that MSVC does.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

nielsm posted:

This, but check if your compiler doesn't have an intrinsic function to generate the breakpoint. I know that MSVC does.
As I recall, both the intrinsic function and the asm in MSVC are frustratingly worse in the debugger than a debugger-added breakpoint - you have to take a couple of steps to get back to the context you're actually wanting to look at. I could be wrong about the asm but the breakpoint function was definitely completely balls.

nielsm
Jun 1, 2009



roomforthetuna posted:

As I recall, both the intrinsic function and the asm in MSVC are frustratingly worse in the debugger than a debugger-added breakpoint - you have to take a couple of steps to get back to the context you're actually wanting to look at. I could be wrong about the asm but the breakpoint function was definitely completely balls.

But at least you can be sure it won't be optimized out. You could set a breakpoint on the breakpoint and then jump over the int3 when it hits!

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
I feel like the volatile variable is what I want. Our code builds/runs on a lot of different platforms so I want something that I am sure will work anywhere with minimal frustration. Thanks.

Xerophyte
Mar 17, 2008

This space intentionally left blank
I need to instantiate subclasses of some abstract class based on the value of a string, i.e. something equivalent to
C++ code:
Foo *createFoo( string &s ) {
  if ( s == "Bar" )
    return new Bar();
  else if ( s == "Baz" )
    return new Baz();
  ...
}
My plan was to have a static factory somewhere to do this, which feels sensible enough. As there will be quite a lot of classes and the system might need to be extended by other people I'd like for subclasses to register themselves in the factory statically at the start of execution, similar to a static {...} initializer block in Java. Best I got from google was someone on stackoverflow suggesting using static variable initialization of some spurious variable to register classes, i.e. when defining class Bar : public Foo {...} include
C++ code:
static Foo* createBar() { return new Bar(); };
static bool g_barIsInitialized = registerInFooFactory( "Bar", createBar );
but that seems very hackish. I'm also not sure what guarantees the standard gives on when static variables are initialized beyond "before they're accessed". Does it always work and is that the recommended pattern?

raminasi
Jan 25, 2005

a last drink with no ice
I'm totally willing to defer to the advice of more knowledgeable people, but in the absence of anything from them I'd say "Anything that relies on complicated static initialization is something to really, really, really avoid." The standard doesn't guarantee any order of static initialization (as far as I know), and so you're forced to hack in your own determinism. There are a number of ways to do this but I've never seen one that doesn't suck. Personally, if this were my project, I'd probably forego the "automatic" registration and make new subclasses explicitly register themselves somewhere.

shrughes
Oct 11, 2008

(call/cc call/cc)
Why are you passing that string s by non-const reference?

You should go with the single createFoo function instead of a bunch of disparate static initializers. The code is less fragile that way, with no worries about somebody trying to create a foo during the static initialization phase. There's no real benefit to requiring that creators of new Foo subclasses remember to register their classes in some static initialization scheme, versus requiring that creators of new Foo subclasses remember to add their classes to some if/then/else list in foo.cpp. Besides, createFoo should really be the function in charge of deciding precisely how to create a Foo from a string, without much a care for what some random Foo subclass thinks about the matter.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

shrughes posted:

You should go with the single createFoo function instead of a bunch of disparate static initializers. The code is less fragile that way, with no worries about somebody trying to create a foo during the static initialization phase. There's no real benefit to requiring that creators of new Foo subclasses remember to register their classes in some static initialization scheme, versus requiring that creators of new Foo subclasses remember to add their classes to some if/then/else list in foo.cpp. Besides, createFoo should really be the function in charge of deciding precisely how to create a Foo from a string, without much a care for what some random Foo subclass thinks about the matter.
Disagreed. If foo is a library or if classes are plugins you don't want people having to dig in your code to get their stuff added. But what you can do is like GrumpyDoctor says, just require things explicitly call a registration function - or, in the case of plugins, require that they contain a function that you can call, which either calls your registration function as a callback or returns values you can pass to your registration function yourself.

The benefits are encapsulation and flexibility.

Xerophyte
Mar 17, 2008

This space intentionally left blank

shrughes posted:

Why are you passing that string s by non-const reference?

Because I'm bad at C++ and I forgot to write const in the hastily-written example code block :v:

The specific use case is that I'm compiling a material description graph (read from Blender right now but the intent is to be generic) to a shading language (currently I can turn this into this, for instance) and it'd be practical for people to be able to write node descriptors and register them for compilation without needing to mess with the compiler itself. I guess I'll just have a method to register nodes and the author can worry about when to call it.

shrughes
Oct 11, 2008

(call/cc call/cc)

roomforthetuna posted:

Disagreed. If foo is a library or if classes are plugins

He didn't say that in his first post.

roomforthetuna posted:

The benefits are encapsulation and flexibility.

Nope, you don't get any more encapsulation, and you don't get any more flexibility in a non-plugin program. It's something to avoid unless you really need it.

Edit: Actually, I haven't used dlls or anything plugin-based in like ten years but from what I remember with the way dlls work, even then you shouldn't use some spooky-action-at-a-distance static initialization stuff to register your classes -- you should communicate that registration stuff explicitly to the program.

Edit II: The one time I would do this is when things are statically compiled and linked and the question of which source files are statically compiled and linked changes in some plugin-plugout like way.

Edit III: The downside of the static initialization stuff in a statically linked program is fairly minimal compared to the amount of posting I'm doing about it -- assuming you do it correctly your code is a bit more brittle than it could be, but it's a self-contained brittleness.

shrughes fucked around with this message at 22:28 on Mar 5, 2013

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
I'm getting an error that I can't figure out (C89 code):

C++ code:
enum notice {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,

};
error: 'notice' defined as wrong kind of tag

I understand (I think) that enums and structs live in the same namespace, but I did a whole-project search and I don't use notice as the name of anything else anywhere. Any idea what's up? Compiler is ARM gcc 4.1 for reference.

ExcessBLarg!
Sep 1, 2001

Otto Skorzeny posted:

error: 'notice' defined as wrong kind of tag
There a struct or union with the tag "notice" being included in the same file. Check the headers.

Are you using any libraries other than libc?

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

Otto Skorzeny posted:

I'm getting an error that I can't figure out (C89 code):

C++ code:
enum notice {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,

};

Uh, this is C89? I don't think you can put a name like that after "notice". I think you have to do:

C++ code:
typedef enum {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,
} notice;

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

ExcessBLarg! posted:

There a struct or union with the tag "notice" being included in the same file. Check the headers.

Are you using any libraries other than libc?

Hrm. I'm using some vendor-supplied libraries that I have the source to, but full-text search including them didn't turn up any structs or unions with the name 'notice'. There was a struct in a header that had a field called 'notice', but it is my understanding that such things shouldn't collide with enum, struct or union tags (and temporarily removing it didn't elminiate the error). Renaming the enum did eliminate the error, however. I suppose I must have missed something when I was grepping.

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip

Suspicious Dish posted:

Uh, this is C89? I don't think you can put a name like that after "notice". I think you have to do:

C++ code:
typedef enum {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,
} notice;

You are wrong. The following is valid C89:

C++ code:
enum cardsuit {
   CLUBS,
   DIAMONDS,
   HEARTS,
   SPADES
};
 
struct card {
   enum cardsuit suit;
   short int value;
} hand[13];
 
enum cardsuit trump;
e: incidentally, I wound up looking this up in the standard

quote:

3.5.2.2 Enumeration specifiers

Syntax

enum-specifier:
enum identifier<opt> { enumerator-list }
enum identifier

enumerator-list:
enumerator
enumerator-list , enumerator

enumerator:
enumeration-constant
enumeration-constant = constant-expression

Constraints

The expression that defines the value of an enumeration constant
shall be an integral constant expression that has a value
representable as an int.

Semantics

The identifiers in an enumerator list are declared as constants
that have type int and may appear wherever such are permitted./52/ An
enumerator with = defines its enumeration constant as the value of the
constant expression. If the first enumerator has no = , the value of
its enumeration constant is 0. Each subsequent enumerator with no =
defines its enumeration constant as the value of the constant
expression obtained by adding 1 to the value of the previous
enumeration constant. (A combination of both forms of enumerators may
produce enumeration constants with values that duplicate other values
in the same enumeration.) The enumerators of an enumeration are also
known as its members.

Each enumerated type shall be compatible with an integer type; the
choice of type is implementation-defined.

Example

enum hue { chartreuse, burgundy, claret=20, winedark };
/*...*/
enum hue col, *cp;
/*...*/
col = claret;
cp = &col;
/*...*/
/*...*/ (*cp != burgundy) /*...*/

makes hue the tag of an enumeration, and then declares col as an
object that has that type and cp as a pointer to an object that has
that type. The enumerated values are in the set {0, 1, 20, 21}.


3.5.2.3 Tags

A type specifier of the form

struct-or-union identifier { struct-declaration-list }
enum identifier { enumerator-list }

declares the identifier to be the tag of the structure, union, or
enumeration specified by the list. The list defines the structure
content ,union content ,or enumeration content .If this declaration of
the tag is visible, a subsequent declaration that uses the tag and
that omits the bracketed list specifies the declared structure, union,
or enumerated type. Subsequent declarations in the same scope shall
omit the bracketed list.

Blotto Skorzany fucked around with this message at 23:43 on Mar 5, 2013

ExcessBLarg!
Sep 1, 2001

Suspicious Dish posted:

Uh, this is C89? I don't think you can put a name like that after "notice".
"enum notice {...};" defines the type "enum notice", but not the type "notice" (as it would do in C++).

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I'm wrong. OK!

ctz
Feb 6, 2003

Otto Skorzeny posted:

I'm getting an error that I can't figure out (C89 code):

C++ code:
enum notice {
	NOTICE_VERSION = 0,
	NOTICE_LOGGING,
	NOTICE_WARMUP_LEFT,
	NOTICE_WARMUP_RIGHT,

};
error: 'notice' defined as wrong kind of tag

I understand (I think) that enums and structs live in the same namespace, but I did a whole-project search and I don't use notice as the name of anything else anywhere. Any idea what's up? Compiler is ARM gcc 4.1 for reference.

Look at your code once it has been preprocessed. For gcc, that's gcc -E. This should give you a huge translation unit with all the definitions in-play at the point of your error.

raminasi
Jan 25, 2005

a last drink with no ice
How workable is it to expose a C API that includes structures? I figure the choices are "assume it will always work," "assume it will never work," or something in-between. The specific thing I'm worried about is struct layout and portability. I'm imagining something like:
C code:
typedef struct foo {
    int something;
    double something_else;
    int a_third_thing;
    char blah_blah_blah[SOME_DEFINED_CONSTANT];
} butt; // or whatever this syntax is supposed to look like, I can look it up
Assuming that this is workable, what's the most elegant way to account for the fact that these will actually be consumed by C++? (I'm not exposing C++ so that clients can use platforms other than the one I happened to compile with.) The way to define structures is different, so as I see it I can either have two parallel header files (ugh) or some kind of macro gadgetry controlled by #ifdef __cplusplus that will expand into either the C definition or the C++ one (also ugh). Is there some simpler way I'm missing?

Adbot
ADBOT LOVES YOU

Shugojin
Sep 6, 2007

THE TAIL THAT BURNS TWICE AS BRIGHT...


I asked this a while ago and got distracted, so I'll ask more specifically.

I am tasked to read in a data file of three columns (point) (value) (uncertainty) and feed it to something that's ported from Numerical Recipes in C to use GSL libraries that will do a Levenberg-Marqardt fit.

I am reading the data file like this:
code:
float nu[size];
float phi[size];
float sigma[size];
for (i = 0; i<100; i++)
	{
		if ( fscanf (data ,"%f %f %f", &nu[i], &phi[i], &sigma[i]) != 3 )
            {
               break;
            }
		
	}
That much works.

I am using this:
code:
void fit(float nu[],float phi[],float sig[],int n,float a[],int ia[],int ma,
          void (*func)(float,float *,float *,float *,int),char *label)
{
     float **covar,**alpha,chisq,alamda,chiold,lamold;
     int i = 0;

     /* allocate working matrices */

     covar = matrix(1,2,1,2);
     alpha = matrix(1,2,1,2);

     /* initialize */

     alamda = -1.0;
     chiold = HUGE_VAL;
     lamold = 0.001;

     /* iterate to best fit */

	do
	{
		mrqmin(nu-1,phi-1,sig-1,n,a-1,ia-1,ma,covar,alpha,&chisq,func,&alamda);
	}
	 while (i < n);
}
To call the mrqmin.c routine I've been given.

Lorentzian isn't really coded for what I'll need it to do yet, but as I'm reading this I want to be declaring it as:

code:
void Lorentzian(float phi, float *alpha, float *nu, float *nunought, int index)
{
	(stuff to define a Lorentzian)
	
}
I get all these warnings/errors:
code:
Fit.c: In function ‘main’:
Fit.c:77:1: error: incompatible type for argument 1 of ‘Lorentzian’
Fit.c:9:6: note: expected ‘float’ but argument is of type ‘float *’
Fit.c:77:1: warning: passing argument 2 of ‘Lorentzian’ from incompatible pointer type [enabled by default]
Fit.c:9:6: note: expected ‘float *’ but argument is of type ‘float (*)[(sizetype)(size)]’
Fit.c:77:1: warning: passing argument 3 of ‘Lorentzian’ from incompatible pointer type [enabled by default]
Fit.c:9:6: note: expected ‘float *’ but argument is of type ‘float (*)[(sizetype)(size)]’
Fit.c:77:1: warning: passing argument 4 of ‘Lorentzian’ from incompatible pointer type [enabled by default]
Fit.c:9:6: note: expected ‘float *’ but argument is of type ‘float (*)[(sizetype)(size)]’
Fit.c:77:1: warning: passing argument 6 of ‘fit’ from incompatible pointer type [enabled by default]
Fit.c:21:6: note: expected ‘int *’ but argument is of type ‘float *’
Fit.c:77:1: warning: passing argument 9 of ‘fit’ from incompatible pointer type [enabled by default]
Fit.c:21:6: note: expected ‘char *’ but argument is of type ‘char **’
The code as defined is pretty much exactly as Numerical Recipes in C defines their mqrmin.c function, you can find that section beginning on page 683 of this older version they have for free viewing on their website.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply