I want to try out Critcl to enhance memory performance using a Z-order curve for a 2d-grid. What I need from Critcl is allocation, setter, getter and some size info. Reading about the Critcl ByteArray and examples does not make me confident on how to do it.
How do I create and return a ByteArray (i.e. Z-order curve)?
Any caveats I should know about when using ByteArray?
According to the documentation, you should be using the bytes type instead (when you get a pointer to a structure that has a len field with the number of bytes in it, and an s field that is the pointer to the actual read only block of bytes. (As a char * and not an unsigned char * for reasons I don't know. And why it isn't const is another mystery to me; there are cases where that's indeed true, but you need to look at the o field to figure that out.)
To return a byte array, you use the object (or object0) result type, and make the object with, for example, Tcl_NewByteArrayObj(), or Tcl_NewObj() and Tcl_SetByteArrayLength().
Here's an example (just the command definition) that does trivial byte reversing (since I don't understand Z-order curves at all):
critcl::cproc example {bytes dataPtr} object0 {
Tcl_Obj *result = Tcl_NewObj();
unsigned char *targetBytes = Tcl_SetByteArrayLength(result, dataPtr->len);
for (int i = 0, j = dataPtr->len - 1; j >= 0; i++, j--) {
targetBytes[i] = (unsigned byte) dataPtr->s[j];
}
return result;
}
Naturally, you'll want to read the Critcl usage guide when getting this to work, and if you're going to produce errors (by returning NULL), remember to set an error message in the interpreter. You can get access to that by using Tcl_Interp* interp as your first pseudo-argument to the command you create with critcl::cproc (it's documented, but easily missed).
I'm trying to write a MySQL UDF in Go with cgo, in which I have a basic one functioning, but there's little bits and pieces that I can't figure out because I have no idea what some of the C variables are in terms of Go.
This is an example that I have written in C that forces the type of one of the MySQL parameters to an int
my_bool unhex_sha3_init(UDF_INIT *initid, UDF_ARGS *args, char *message) {
if (args->arg_count != 2) {
strcpy(message, "`unhex_sha3`() requires 2 parameters: the message part, and the bits");
return 1;
}
args->arg_type[1] = INT_RESULT;
initid->maybe_null = 1; //can return null
return 0;
}
And that works fine, but then I try to do the same/similar thing with this other function in Go like this
//export get_url_param_init
func get_url_param_init(initid *C.UDF_INIT, args *C.UDF_ARGS, message *C.char) C.my_bool {
if args.arg_count != 2 {
message = C.CString("`get_url_param` require 2 parameters: the URL string and the param name")
return 1
}
(*args.arg_type)[0] = C.STRING_RESULT
(*args.arg_type)[1] = C.STRING_RESULT
initid.maybe_null = 1
return 0
}
With this build error
./main.go:24: invalid operation: (*args.arg_type)[0] (type uint32 does
not support indexing)
And I'm not totally sure what that means. Shouldn't this be a slice of some sort, not a uint32?
And this is where it'd be super helpful have some way of dumping the args struct somewhere somehow (maybe even in Go syntax as a super plus) so that I can tell what I'm working with.
Well I used spew to dump the variable contents to a tmp file inside the init function (commenting out the lines that made it not compile) and I got this
(string) (len=3) "%#v"
(*main._Ctype_struct_st_udf_args)(0x7ff318006af8)({
arg_count: (main._Ctype_uint) 2,
_: ([4]uint8) (len=4 cap=4) {
00000000 00 00 00 00 |....|
},
arg_type: (*uint32)(0x7ff318006d18)(0),
args: (**main._Ctype_char)(0x7ff318006d20->0x7ff3180251b0)(0),
lengths: (*main._Ctype_ulong)(0x7ff318006d30)(0),
maybe_null: (*main._Ctype_char)(0x7ff318006d40)(0),
attributes: (**main._Ctype_char)(0x7ff318006d58->0x7ff318006b88)(39),
attribute_lengths: (*main._Ctype_ulong)(0x7ff318006d68)(2),
extension: (unsafe.Pointer) <nil>
})
Alright so huge help with #JimB who stuck with me even though I'm clearly less adept with Go (and especially CGO) but I've got a working version of my UDF, which is an easy and straight forward (and fast) function that pulls a single parameter out of a URL string and decodes it correctly and what not (e.g. %20 gets returned as a space, basically how you would expect it to work).
This seemed incredibly tricky with a pure C UDF because I don't really know C (as well as I know other languages), and there's a lot that can go wrong with URL parsing and URL parameter decoding, and native MySQL functions are slow (and there's not really a good, clean way to do the decoding either), so Go seemed like the better-than-perfect candidate for this kind of problem, for strong performance, ease of writing, and wide variety of easy to use built ins & third party libraries.
The full UDF and it's installation/usage instructions are here https://github.com/StirlingMarketingGroup/mysql-get-url-param/blob/master/main.go
First problem was debugging output. And I did that by Fprintfing to a tmp file instead of the standard output, so that I could check the file to see variable dumps.
t, err := ioutil.TempFile(os.TempDir(), "get-url-param")
fmt.Fprintf(t, "%#v\n", args.arg_type)
And then after I got my output (I was expecting args.arg_type to be an array like it is in C, but instead was a number) I needed to convert the data referenced by that number (the pointer to the start of the C array) to a Go array so I could set it's values.
argsTypes := *(*[2]uint32)(unsafe.Pointer(args.arg_type))
argsTypes[0] = C.STRING_RESULT
argsTypes[1] = C.STRING_RESULT
I'm afraid to ask questions in case it turns out to be stupid... But I tried to search and don't see the same situation.
I'm retrofitting a std::vector into some existing legacy code that is mostly C style. Our next major release which isn't due for a year or two will jettison a lot of the legacy code. But for now, the way we work is, every project gets recompiled for the customer, depending on specs. Some projects are on Visual Studio 2008, some 2010, etc. My added std::vector code I'm working on has no visible problems when compiled with 2013, but, I get crashes within the STL code when running VS 2008 SP1.
The existing code has a struct, and a fixed size array in it:
#define MAX_REMOTE_CONN 75
typedef struct {
int rno;
int adrs;
bool integ_pending;
} RTUref;
typedef struct {
char device[64];
int port;
RTUref RTU[MAX_REMOTE_CONN];
// more stuff...
} Connect_Info;
So, my basic goal is to get rid of the hard coded size limit to the RTU array. So, I have revised it like this:
class{
public:
int rno;
int adrs;
bool integ_pending;
} RTUref;
typedef std::vector <RTUref> RTUlist;
typedef struct {
char device[64];
int port;
RTUlist RTU;
// more stuff...
} Connect_Info;
The Connect_Info structs are allocated using our own memory manager. Don't know much about it other than it is supposed to be more efficient than use malloc() and free(). I'm guessing that the constructor for RTU doesn't get called since the struct it is contained in data allocated by our own memory manager?
Nevertheless, the code where I size the array, put values into the array all at least seem to work okay. But, when I call .clear() I get a crash from within the STL. And as I said, only if I use 2008. If I use 2013, I don't get that crash.
Assuming pct is a pointer to an allocated Connect_Info structure, the the line:
pct->RTU.clear();
Generates a crash on VS 2008. I am able to resize and add elements to the array. And I even tried to add a check that I don't clear unless the size is greater than zero like so:
if (pct->RTU.size() > 0)
pct->RTU.clear();
And I still get the crash on the clear.
So, I made the educated guess that I need to call a constructor. But, I wasn't quite sure of how to do it. But, in the code where the Connect_Info struct is allocated, I tried to add contructor code like this:
pct->RTU = RTUlist();
It compiles. But, I then get a crash in the STL on that line.
I haven't yet tried to build a small contained test program, as I'm not even sure that I will be able to reproduce the problem without our memory manager. But, I will try if that is what I need to do. I thought maybe someone might see obviously what I'm doing wrong. I'm fairly novice to the STL.
A little background: there is a term in C++ called "POD Type" (or "Plain Old Data Type").
There are verbose rules, but basically things that may do special things on allocations, deallocations, or copies are not POD types. The original Connect_Info was a POD type since it didn't do special things at those times and didn't have any non-POD members.
However, since you added a std::vector (which is not a POD type because it has to do special things at allocation, deallocation, copy, etc (because it allocates memory)), Connect_Info is not a POD type.
POD types can be allocated safely with malloc and deallocated with free since they don't do special things. However, non-POD types cannot (except in exceedingly rare cases which you'll first see after several years of programming C++) be allocated like that.
C only has POD types, so malloc is perfectly acceptable. There are a few options you can do:
int main ( ... )
{
Connect_Info * info = new Connect_Info() ;
std::cout << info->port << std::endl ;
delete info ;
}
Or
Connect_Info * makeOne ()
{
void * ptr = malloc ( sizeof(Connect_Info) ) ;
if ( ! ptr ) return 0 ;
return new (ptr) Connect_Info () ; // "In-Place constructor"
}
void deleteOne ( Connect_Info * info )
{
if ( ! ptr ) return ;
info = info->~Connect_Info() ; // manually call its destructor with the weirdest syntax ever
// Note: I'm not 100% sure this call to 'free' is right because the in-place new can return a different pointer, but I don't know how to the get the original back
free ( static_cast<void*>(info) ) ;
}
int main ( ... )
{
Connect_Info * info = makeOne ()
std::cout << info->port << std::endl ;
deleteOne ( info ) ;
}
If you have boost available (or C++11, which you probably don't), this is a MUCH better option (and only uses header components of boost):
boost::shared_ptr<Connect_Info> makeOne ()
{
return boost::make_shared<Connect_Info> () ;
}
int main ( ... )
{
boost::shared_ptr<Connect_Info> info = makeOne ()
std::cout << info->port << std::endl ;
// nothing else: shared_ptr takes care of that for you
}
(If you have C++11, use std::shared_ptr and std::make_shared)
Let's say I have 1000 functions defined as follows
void func dummy1(int a);
void func dummy2(int a, int aa);
void func dummy3(int a, int aa, int aaa);
.
.
.
void func dummy1000(int a, int aa, int aaa, ...);
I want to write a function that takes an integer, n (n < 1000) and calls nth dummy function (in case of 10, dummy10) with exactly n arguments(arguments can be any integer, let's say 0) as required. I know this can be achieved by writing a switch case statement with 1000 cases which is not plausible.
In my opinion, this cannot be achieved without recompilation at run time so languages like java, c, c++ will never let such a thing happen.
Hopefully, there is a way to do this. If so I am curious.
Note: This is not something that I will ever use, I asked question just because of my curiosity.
In modern functional languages, you can make a list of functions which take a list as an argument. This will arguably solve your problem, but it is also arguably cheating, as it is not quite the statically-typed implementation your question seems to imply. However, it is pretty much what dynamic languages such as Python, Ruby, or Perl do when using "manual" argument handling...
Anyway, the following is in Haskell: it supplies the nth function (from its first argument fs) a list of n copies of the second argument (x), and returns the result. Of course, you will need to put together the list of functions somehow, but unlike a switch statement this list will be reusable as a first-class argument.
selectApplyFunction :: [ [Int] -> a ] -> Int -> Int -> a
selectApplyFunction fs x n = (fs !! (n-1)) (replicate n x)
dummy1 [a] = 5 * a
dummy2 [a, b] = (a + 3) * b
dummy3 [a, b, c] = (a*b*c) / (a*b + b*c + c*a)
...
myFunctionList = [ dummy1, dummy2, dummy3, ... ]
-- (myfunction n) provides n copies of the number 42 to the n'th function
myFunction = selectApplyFunction myFunctionList 42
-- call the 666'th function with 666 copies of 42
result = myFunction 666
Of course, you will get an exception if n is greater than the number of functions, or if the function can't handle the list it is given. Note, too, that it is poor Haskell style -- mainly because of the way it abuses lists to (abusively) solve your problem...
No, you are incorrect. Most modern languages support some form of Reflection that will allow you to call a function by name and pass params to it.
You can create an array of functions in most of modern languages.
In pseudo code,
var dummy = new Array();
dummy[1] = function(int a);
dummy[2] = function(int a, int aa);
...
var result = dummy[whateveryoucall](1,2,3,...,whateveryoucall);
In functional languages you could do something like this, in strongly typed ones, like Haskell, the functions must have the same type, though:
funs = [reverse, tail, init] -- 3 functions of type [a]->[a]
run fn arg = (funs !! fn) $ args -- applies function at index fn to args
In object oriented languages, you can use function objects and reflection together to achieve exactly what you want. The problem of the variable number of arguments is solved by passing appropriate POJOs (recalling C stucts) to the function object.
interface Functor<A,B> {
public B compute(A input);
}
class SumInput {
private int x, y;
// getters and setters
}
class Sum implements Functor<SumInput, Integer> {
#Override
public Integer compute(SumInput input) {
return input.getX() + input.getY();
}
}
Now imagine you have a large number of these "functors". You gather them in a configuration file (maybe an XML file with metadata about each functor, usage scenarios, instructions, etc...) and return the list to the user.
The user picks one of them. By using reflection, you can see what is the required input and the expected output. The user fills in the input, and by using reflection you instantiate the functor class (newInstance()), call the compute() function and get the output.
When you add a new functor, you just have to change the list of the functors in the config file.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
When learning a new programming language, one of the possible roadblocks you might encounter is the question whether the language is, by default, pass-by-value or pass-by-reference.
So here is my question to all of you, in your favorite language, how is it actually done? And what are the possible pitfalls?
Your favorite language can, of course, be anything you have ever played with: popular, obscure, esoteric, new, old...
Here is my own contribution for the Java programming language.
first some code:
public void swap(int x, int y)
{
int tmp = x;
x = y;
y = tmp;
}
calling this method will result in this:
int pi = 3;
int everything = 42;
swap(pi, everything);
System.out.println("pi: " + pi);
System.out.println("everything: " + everything);
"Output:
pi: 3
everything: 42"
even using 'real' objects will show a similar result:
public class MyObj {
private String msg;
private int number;
//getters and setters
public String getMsg() {
return this.msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
//constructor
public MyObj(String msg, int number) {
setMsg(msg);
setNumber(number);
}
}
public static void swap(MyObj x, MyObj y)
{
MyObj tmp = x;
x = y;
y = tmp;
}
public static void main(String args[]) {
MyObj x = new MyObj("Hello world", 1);
MyObj y = new MyObj("Goodbye Cruel World", -1);
swap(x, y);
System.out.println(x.getMsg() + " -- "+ x.getNumber());
System.out.println(y.getMsg() + " -- "+ y.getNumber());
}
"Output:
Hello world -- 1
Goodbye Cruel World -- -1"
thus it is clear that Java passes its parameters by value, as the value for pi and everything and the MyObj objects aren't swapped.
be aware that "by value" is the only way in java to pass parameters to a method. (for example a language like c++ allows the developer to pass a parameter by reference using '&' after the parameter's type)
now the tricky part, or at least the part that will confuse most of the new java developers: (borrowed from javaworld)
Original author: Tony Sintes
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
"Output
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0"
tricky successfully changes the value of pnt1!
This would imply that Objects are passed by reference, this is not the case!
A correct statement would be: the Object references are passed by value.
more from Tony Sintes:
The method successfully alters the
value of pnt1, even though it is
passed by value; however, a swap of
pnt1 and pnt2 fails! This is the major
source of confusion. In the main()
method, pnt1 and pnt2 are nothing more
than object references. When you pass
pnt1 and pnt2 to the tricky() method,
Java passes the references by value
just like any other parameter. This
means the references passed to the
method are actually copies of the
original references. Figure 1 below
shows two references pointing to the
same object after Java passes an
object to a method.
(source: javaworld.com)
Conclusion or a long story short:
Java passes it parameters by value
"by value" is the only way in java to pass a parameter to a method
using methods from the object given as parameter will alter the object as the references point to the original objects. (if that method itself alters some values)
useful links:
http://www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
http://www.ibm.com/developerworks/java/library/j-passbyval/
http://www.ibm.com/developerworks/library/j-praxis/pr1.html
http://javadude.com/articles/passbyvalue.htm
Here is another article for the c# programming language
c# passes its arguments by value (by default)
private void swap(string a, string b) {
string tmp = a;
a = b;
b = tmp;
}
calling this version of swap will thus have no result:
string x = "foo";
string y = "bar";
swap(x, y);
"output:
x: foo
y: bar"
however, unlike java c# does give the developer the opportunity to pass parameters by reference, this is done by using the 'ref' keyword before the type of the parameter:
private void swap(ref string a, ref string b) {
string tmp = a;
a = b;
b = tmp;
}
this swap will change the value of the referenced parameter:
string x = "foo";
string y = "bar";
swap(x, y);
"output:
x: bar
y: foo"
c# also has a out keyword, and the difference between ref and out is a subtle one.
from msdn:
The caller of a method which takes an
out parameter is not required to
assign to the variable passed as the
out parameter prior to the call;
however, the callee is required to
assign to the out parameter before
returning.
and
In contrast ref parameters are
considered initially assigned by the
callee. As such, the callee is not
required to assign to the ref
parameter before use. Ref parameters
are passed both into and out of a
method.
a small pitfall is, like in java, that objects passed by value can still be changed using their inner methods
conclusion:
c# passes its parameters, by default, by value
but when needed parameters can also be passed by reference using the ref keyword
inner methods from a parameter passed by value will alter the object (if that method itself alters some values)
useful links:
http://msdn.microsoft.com/en-us/vcsharp/aa336814.aspx
http://www.c-sharpcorner.com/UploadFile/saragana/Willswapwork11162005012542AM/Willswapwork.aspx
http://en.csharp-online.net/Value_vs_Reference
Python uses pass-by-value, but since all such values are object references, the net effect is something akin to pass-by-reference. However, Python programmers think more about whether an object type is mutable or immutable. Mutable objects can be changed in-place (e.g., dictionaries, lists, user-defined objects), whereas immutable objects can't (e.g., integers, strings, tuples).
The following example shows a function that is passed two arguments, an immutable string, and a mutable list.
>>> def do_something(a, b):
... a = "Red"
... b.append("Blue")
...
>>> a = "Yellow"
>>> b = ["Black", "Burgundy"]
>>> do_something(a, b)
>>> print a, b
Yellow ['Black', 'Burgundy', 'Blue']
The line a = "Red" merely creates a local name, a, for the string value "Red" and has no effect on the passed-in argument (which is now hidden, as a must refer to the local name from then on). Assignment is not an in-place operation, regardless of whether the argument is mutable or immutable.
The b parameter is a reference to a mutable list object, and the .append() method performs an in-place extension of the list, tacking on the new "Blue" string value.
(Because string objects are immutable, they don't have any methods that support in-place modifications.)
Once the function returns, the re-assignment of a has had no effect, while the extension of b clearly shows pass-by-reference style call semantics.
As mentioned before, even if the argument for a is a mutable type, the re-assignment within the function is not an in-place operation, and so there would be no change to the passed argument's value:
>>> a = ["Purple", "Violet"]
>>> do_something(a, b)
>>> print a, b
['Purple', 'Violet'] ['Black', 'Burgundy', 'Blue', 'Blue']
If you didn't want your list modified by the called function, you would instead use the immutable tuple type (identified by the parentheses in the literal form, rather than square brackets), which does not support the in-place .append() method:
>>> a = "Yellow"
>>> b = ("Black", "Burgundy")
>>> do_something(a, b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in do_something
AttributeError: 'tuple' object has no attribute 'append'
Since I haven't seen a Perl answer yet, I thought I'd write one.
Under the hood, Perl works effectively as pass-by-reference. Variables as function call arguments are passed referentially, constants are passed as read-only values, and results of expressions are passed as temporaries. The usual idioms to construct argument lists by list assignment from #_, or by shift tend to hide this from the user, giving the appearance of pass-by-value:
sub incr {
my ( $x ) = #_;
$x++;
}
my $value = 1;
incr($value);
say "Value is now $value";
This will print Value is now 1 because the $x++ has incremented the lexical variable declared within the incr() function, rather than the variable passed in. This pass-by-value style is usually what is wanted most of the time, as functions that modify their arguments are rare in Perl, and the style should be avoided.
However, if for some reason this behaviour is specifically desired, it can be achieved by operating directly on elements of the #_ array, because they will be aliases for variables passed into the function.
sub incr {
$_[0]++;
}
my $value = 1;
incr($value);
say "Value is now $value";
This time it will print Value is now 2, because the $_[0]++ expression incremented the actual $value variable. The way this works is that under the hood #_ is not a real array like most other arrays (such as would be obtained by my #array), but instead its elements are built directly out of the arguments passed to a function call. This allows you to construct pass-by-reference semantics if that would be required. Function call arguments that are plain variables are inserted as-is into this array, and constants or results of more complex expressions are inserted as read-only temporaries.
It is however exceedingly rare to do this in practice, because Perl supports reference values; that is, values that refer to other variables. Normally it is far clearer to construct a function that has an obvious side-effect on a variable, by passing in a reference to that variable. This is a clear indication to the reader at the callsite, that pass-by-reference semantics are in effect.
sub incr_ref {
my ( $ref ) = #_;
$$ref++;
}
my $value = 1;
incr(\$value);
say "Value is now $value";
Here the \ operator yields a reference in much the same way as the & address-of operator in C.
There's a good explanation here for .NET.
A lot of people are surprise that reference objects are actually passed by value (in both C# and Java). It's a copy of a stack address. This prevents a method from changing where the object actually points to, but still allows a method to change the values of the object. In C# its possible to pass a reference by reference, which means you can change where an actual object points to.
Don't forget there is also pass by name, and pass by value-result.
Pass by value-result is similar to pass by value, with the added aspect that the value is set in the original variable that was passed as the parameter. It can, to some extent, avoid interference with global variables. It is apparently better in partitioned memory, where a pass by reference could cause a page fault (Reference).
Pass by name means that the values are only calculated when they are actually used, rather than at the start of the procedure. Algol used pass-by-name, but an interesting side effect is that is it very difficult to write a swap procedure (Reference). Also, the expression passed by name is re-evaluated each time it is accessed, which can also have side effects.
Whatever you say as pass-by-value or pass-by-reference must be consistent across languages. The most common and consistent definition used across languages is that with pass-by-reference, you can pass a variable to a function "normally" (i.e. without explicitly taking address or anything like that), and the function can assign to (not mutate the contents of) the parameter inside the function and it will have the same effect as assigning to the variable in the calling scope.
From this view, the languages are grouped as follows; each group having the same passing semantics. If you think that two languages should not be put in the same group, I challenge you to come up with an example that distinguishes them.
The vast majority of languages including C, Java, Python, Ruby, JavaScript, Scheme, OCaml, Standard ML, Go, Objective-C, Smalltalk, etc. are all pass-by-value only. Passing a pointer value (some languages call it a "reference") does not count as pass by reference; we are only concerned about the thing passed, the pointer, not the thing pointed to.
Languages such as C++, C#, PHP are by default pass-by-value like the languages above, but functions can explicitly declare parameters to be pass-by-reference, using & or ref.
Perl is always pass-by-reference; however, in practice people almost always copy the values after getting it, thus using it in a pass-by-value way.
by value
is slower than by reference since the system has to copy the parameter
used for input only
by reference
faster since only a pointer is passed
used for input and output
can be very dangerous if used in conjunction with global variables
Concerning J, while there is only, AFAIK, passing by value, there is a form of passing by reference which enables moving a lot of data. You simply pass something known as a locale to a verb (or function). It can be an instance of a class or just a generic container.
spaceused=: [: 7!:5 <
exectime =: 6!:2
big_chunk_of_data =. i. 1000 1000 100
passbyvalue =: 3 : 0
$ y
''
)
locale =. cocreate''
big_chunk_of_data__locale =. big_chunk_of_data
passbyreference =: 3 : 0
l =. y
$ big_chunk_of_data__l
''
)
exectime 'passbyvalue big_chunk_of_data'
0.00205586720663967
exectime 'passbyreference locale'
8.57957102144893e_6
The obvious disadvantage is that you need to know the name of your variable in some way in the called function. But this technique can move a lot of data painlessly. That's why, while technically not pass by reference, I call it "pretty much that".
PHP is also pass by value.
<?php
class Holder {
private $value;
public function __construct($value) {
$this->value = $value;
}
public function getValue() {
return $this->value;
}
}
function swap($x, $y) {
$tmp = $x;
$x = $y;
$y = $tmp;
}
$a = new Holder('a');
$b = new Holder('b');
swap($a, $b);
echo $a->getValue() . ", " . $b->getValue() . "\n";
Outputs:
a b
However in PHP4 objects were treated like primitives. Which means:
<?php
$myData = new Holder('this should be replaced');
function replaceWithGreeting($holder) {
$myData->setValue('hello');
}
replaceWithGreeting($myData);
echo $myData->getValue(); // Prints out "this should be replaced"
By default, ANSI/ISO C uses either--it depends on how you declare your function and its parameters.
If you declare your function parameters as pointers then the function will be pass-by-reference, and if you declare your function parameters as not-pointer variables then the function will be pass-by-value.
void swap(int *x, int *y); //< Declared as pass-by-reference.
void swap(int x, int y); //< Declared as pass-by-value (and probably doesn't do anything useful.)
You can run into problems if you create a function that returns a pointer to a non-static variable that was created within that function. The returned value of the following code would be undefined--there is no way to know if the memory space allocated to the temporary variable created in the function was overwritten or not.
float *FtoC(float temp)
{
float c;
c = (temp-32)*9/5;
return &c;
}
You could, however, return a reference to a static variable or a pointer that was passed in the parameter list.
float *FtoC(float *temp)
{
*temp = (*temp-32)*9/5;
return temp;
}