obfuscated C++ Translation: float&, two for loops - c++

I was reading Hacker News and this article came up. It contains a raytracer that the code is written on the back of a business card. I decided it would be a good academic challenge to translate the c++ to python, but there's a few concepts I'm stuck on.
First, this function comes up: i T(v o,v d,f& t,v& n){...} Which is translated to int Tracer(vector o, vector d, float& t, vector& n){...} What does the float& mean? I know that in other places & is used as a == is that the case here? Can you do that in c++?
Second, I noticed these three lines:
for(i k=19;k--;) //For each columns of objects
for(i j=9;j--;) //For each line on that columns
if(G[j]&1<<k){
I know the << is a the bit shift, and I assume the & is ==. Are the for loops just like one for loop in an other?
Finally, this line: v p(13,13,13); I am not quite sure what it does. Does it create a class labeled by p that extends v (vector) with the defaults of 13,13,13?
These are probably dumb questions, but I want to see if I can understand this and my searching didn't come up with anything. Thank you in advance!

What does the float& mean?
Here, & means "reference", so the argument is passed by reference.
I know that in other places & is used as a == is that the case here?
& means various things in various contexts, but it never means ==. In this case, it's not an operator either; it's part of a type specification, meaning that it's a reference type.
I know the << is a the bit shift, and I assume the & is ==
No, it's a bitwise and operator. The result has its bits set where a bit is set in both operands. Here, with 1<<k as one operand, the result is the kth bit of G[j]; so this tests whether that bit is set.
Are the for loops just like one for loop in an other?
Yes. If you don't use braces around a for-loop's body, then the body is a single statement. So in this case, the body of the first loop is the second loop. To make this clear, I would recommend indenting the body of the loop, and using braces whether or not they are strictly necessary. But of course, I don't write (deliberately) obfuscated code.
Finally, this line: v p(13,13,13);
v is a class with a constructor taking three arguments. This declares an variable called p, of type v, initialised using that constructor; i.e. the three co-ordinates are initialised to 13.

When you seeVector& n it is referencing the vector passed into the function. This means that you can change n inside of this function without having to copy it to another Vector or without returning the Vector. This previous answer should be helpful to you.

Related

How to solve Syntax Error in Data Statement?

Hi I am new here and want to solve this problem:
do k=1,31
Data H(1,k)/0/
End do
do l=1,21
Data H(l,1)/0.5*(l-1)/
End do
do m=31,41
Data H(17,m)/0/
End do
do n=17,21
Data H(n,41)/0.5*(n-17)/
End do
I get error for l and n saying that it is a syntax error in DATA statement. Anyone know how to solve this problem?
You have three problems here, and not just with the "l" and "n" loops.
The first problem is that the values in a data statement cannot be arbitrary expressions. In particular, they must be constants; 0.5*(l-1) is not a constant.
The second problem is that the bounds in the object lists must also be constant (expressions); l is not a constant expression.
For the first, it's also worth noting that * in a data value list has a special meaning, and it isn't the multiplication operator. * gives a repeat count, and a repeat count of 0.5 is not valid.
You can fix the second point quite simply, by using such constructions as
data H(1,1:31) /31*0./ ! Note the repeat count specifier
outside a loop, or using an implied loop
data (H(1,k),k=1,31) /31*0./
To do something for the "l" loop is more tedious
data H(1:21,1) /0., 0.5, 1., 1.5, ... /
and we have to be very careful about the number of values specified. This cannot be dynamic.
The third problem is that you cannot specify explicit initialization for an element more than once. Look at your first two loops: if this worked you'd be initializing H(1,1) twice. Even though the same value is given, this is still invalid.
Well, actually you have four problems. The fourth is related to the point about dynamic number of values. You probably don't want to be doing explicit initialization. Whilst it's possible to do what it looks like you want to do, just use assignment where these restrictions don't apply.
do l=1,21
H(l,1) = 0.5*(l-1)
End do
Yes, there are times when complicated explicit initialization is a desirable thing, but in this case, in what I assume is new code, keeping things simple is good. An "initialization" portion of your code which does the assignments is far more "modern".

Class function returning invalid lvalue

Hi I am now writing a program handling matrix manipulation and I am struggling on the error handling issue in a member function.
Given a function
double & MATRIX::elements(int i, int j) const;
it is the function that can return a reference back, so the function can be a
lvalue, e.g.
object.elements(1,2)= 2; // I can change the value matrix element (1,2) to be 2
I assume that some people may enter the index of the matrix wrongly (i.e.invalid value of i and j) that the element (i,j) does not exist. Therefore, I write an if-else statement, however, I wonder what should I return when invalid values of i and j are found?? Can I prevent the function from returning anything so situations like
object.elements(100,100000)= 2; // where the matrix size is only 3x3
won' t happen??
P.S. I store the matrix elements in a dynamic array when I create the object
There are three practical possibilities:
assert the precondition, and rely on testing to root out all invalid calls, or
throw an exception when the precondition is not true, or
return an easily recognized-as-such error value.
In the old days one also included schemes such as calling a user-provided error function, but really what could it do except terminate or throw an exception.
The third possibility, returning a known-as-such error value, may appear unsuitable for your present predicament, which ideally would return a double& which would be immediately used. But in general it's a valid option. For example, it can be implemented as a Boost optional.
In passing, some general advice.
For the given code,
double & MATRIX::elements(int i, int j) const;
usually a const method does not provide read/write access, it defeats the purpose. However there are exceptions, such as for a proxy object. But on the third and gripping hand, the above code is not for such objects.
Also, consider reserving ALL UPPERCASE identifiers for macros. That way you can avoid some name collisions. Remember that macros don't respect scopes, and since a great many people use all uppercase identifiers for macros, while few do otherwise, the chance of a collision, resulting in undesirable text substitution, is greater with uppercase used for ordinary identifiers.

Ternary operator as a command?

In the source-code for nanodns, there is an atypical use of the ternary operator in an attempt to reduce the size of the code:
/* If the incoming packet has an AR record (such as in an EDNS request),
* mark the reply as "NOT IMPLEMENTED"; using a?b:c form to save one byte*/
q[11]?q[3]|=4:1;
It’s not obvious what this line does. At first glance, it looks like it is assigning a value to one of two array elements, but it is not. Rather, it seems to be either or’ing an array element, or else, doing nothing (running the “command” 1).
It looks like it is supposed to be a replacement for this line of code (which is indeed one byte longer):
if(q[11])q[3]|=4;
The literal equivalent would be this:
if (q[11])
q[3]|=4;
else
1;
The ternary operator is typically used as part of an expression, so seeing it used as a standalone command seems odd. Coupled with the seemingly out of place 1, this line almost qualifies as obfuscated code.
I did a quick test and was able to compile and run a C(++) program with data constants as “command”, such as void main() {0; 'a'; "foobar"; false;}. It seems to be a sort of nop command, but I cannot find any information about such usage—Google isn’t very amenable to this type of search query).
Can anyone explain exactly what it is and how it works?
In C and C++ any expression can be made into a statement by putting ; at the end.
Another example is that the expression x = 5 can be made into a statement: x = 5; . Hopefully you agree that this is a good idea.
It would needlessly complicate the language to try and "ban" some subset of expressions from having ; come after them. This code isn't very useful but it is legal.
Please note that the code you linked to is awful and written by a really bad programmer. Particularly, the statement
"It is common practice in tiny C programs to define reused expressions
to make the code smaller"
is complete b***s***. That statement is where things started to go terribly wrong.
The size of the source code has no relation to the size of the compiler executable, nor any relation to that executable's memory consumption, nor any relation to program performance. The only thing it affects is the size of the source code files on the programmers computer, expressed in bytes.
Unless you are programming on some 8086 computer from mid-80s with very limited hard drive space, you never need to "reduce the size of the code". Instead, write readable code.
That being said, since q is an array of characters , the code you linked is equivalent to
if(q[11])
{
(int)(q[3] |= 4);
}
else
{
1;
}
Where 1 is a statement with no side effect, it will get optimized away. It was only placed there because the ?: operator demands a 3rd operator.
The only difference between if statements and the ?: operator is subtle: the ?: implicitly balances the type between the 2nd and 3rd operand.
To increase readability and produce self-documenting code, the code should get rewritten to something like
if (q[AR_INDEX] != 0)
{
q[REPLY_INDEX] |= NOT_IMPLEMENTED;
}
As a side note, there is a bug here: q[2]|=128;. q is of type char, which has implementation-defined signedness, so this line is potentially disastrous. The core problem is that you should never use the char type for bit-wise operations or any form of arithmetic, which is a classic beginner mistake. It must be replaced with uint8_t or unsigned char.

String compare in c++

What is the difference between (x == "x") and ("x" == x) comparison in C++? Let's say x is a std::string. Is there any reason why one would be preferred over the other?
One is a string literal "X", and the other is an instance of std::string. Some advocate having the constant "x" on the left hand side, because that way you would get a compiler error if you use assignment = instead of equality ==:
if ("x" = x) // Error! Trying to assign to const char[]
if (x = "x") // Setting the value of x to be "x", and evaluating "x".
// Probably not what you want.
Other than that, there's really no difference.
I think both calls will result in call to bool std::string operator==(const std::string&, const std::string&).
This is because there are no implicit conversion operators from std::string to const char*, but there is implicit constructor from const char* to std::string.
EDIT:
on g++ 4.4.5 both comparisons works.
Here says the now closed question on Yoda Conditionals:
This is one of the things that I hate
most when I see it in someone else's
code. I know what it means and why
some people do it this way ("what if I
accidentally put '=' instead?"). For
me it's very much like when a child
goes down the stairs counting the
steps out loud.
Anyway, here are my arguments against
it:
It disrupts the natural flow of reading the program code. We, humans,
say "if value is zero" and not "if
zero is value".
Modern compilers warn you when you have an assignment in your condition,
or actually if your condition consists
of just that assignment, which, yes,
looks suspicious anyway
You shouldn't forget to put double '=' when you are comparing values if
you are a programmer. You may as well
forget to put "!" when testing
non-equality.
-mojuba
Accepted answer:
Ah, yes, "Yoda conditionals" ("If zero
the value is, execute this code you
must!"). I always point anyone who
claims they're "better" at tools like
lint(1). This particular problem has
been solved since the late 70s. Most
modern languages won't even compile
this, as they refuse to coerce the
result of the assignment to a boolean.
As others have said, it certainly
isn't a problem, but it does provoke a
bit of cognitive dissonance.
-TMN
I prefer using for NSStrings...
([x isEqualToString:#"x"])
or for c strings
strcmp(str1,str2);
There is no difference between those two conditions, other than maybe something internal. It's like holding two things in your hands, one in each hand, and comparing them - and then basing then factoring in which hand each one is in. ...That's not something that's a factor.

An explanation about Sequence points

Lately, I have seen a lot of questions being asked about output for some crazy yet syntactically allowed code statements like like i = ++i + 1 and i=(i,i++,i)+1;.
Frankly realistically speaking hardly anyone writes any such code in actual programing.To be frank I have never encountered any such code in my professional experience. So I usually end up skipping such questions here on SO. But lately the sheer volume of such Q's being asked makes me think if I am missing out some important theory by skipping such Q's. I gather that the such Q's revolve around Sequence points. I hardly know anything about sequence points to be frank and I am just wondering if not knowing about it is a handicap in some way. So can someone please explain the theory /concept of Sequence points, or If possible point to a resource which explains about the concept. Also, is it worth to invest time in knowing about this concept/theory?
The simplest answer I can think of is:
C++ is defined in terms of an abstract machine. The output of a program executed on the abstract machine is defined ONLY in terms of the order that "side effects" are performed. And Side effects are defined as calls into IO library functions, and changes to variables marked volatile.
C++ compilers are allowed to do whatever they want internally to optimize code, but they cannot change the order of writes to volatile variables, and io calls.
Sequence points define the c/c++ program's heartbeat - side effects before the sequence point are "complete" and side effects after the sequence point have not yet taken place. But, side effects (or, code that can effect a side effect indirectly( within a sequence point can be re-ordered.
Which is why understanding them is important. Without that understanding, your fundamental understanding of what a c++ program is (And how it might be optimized by an agressive compiler) is flawed.
See http://en.wikipedia.org/wiki/Sequence_point.
It's a quite simple concept, so you don't need to invest much time :)
The exact technical details of sequence points can get hairy, yes. But following these guideline solves almost all the practical issues:
If an expression modifies a value, there must be a sequence point between the modification and any other use of that value.
If you're not sure whether two uses of a value are separated by a sequence point or not, break up your code into more statements.
Here "modification" includes assignment operations on the left-hand value in =, +=, etc., and also the ++x, x++, --x, and x-- syntaxes. (It's usually these increment/decrement expressions where some people try to be clever and end up getting into trouble.)
Luckily, there are sequence points in most of the "expected" places:
At the end of every statement or declaration.
At the beginning and end of every function call.
At the built-in && and || operators.
At the ? in a ternary expression.
At the built-in , comma operator. (Most commonly seen in for conditions, e.g. for (a=0, b=0; a<m && b<n; ++a, ++b).) A comma which separates function arguments is not the comma operator and is not a sequence point.
Overloaded operator&&, operator||, and operator, do not cause sequence points. Potential surprises from that fact is one reason overloading them is usually discouraged.
It is worth knowing that sequence points exist because if you don't know about them you can easily write code which seems to run fine in testing but actually is undefined and might fail when you run it on another computer or with different compile options. In particular if you write for example x++ as part of a larger expression that also includes x you can easily run into problems.
I don't think it is necessary to learn all the rules fully - but you need to know when you need to check the specification, or perhaps better - when to rewrite your code to make it so that you aren't relying on sequence points rules if a simpler design would work too.
int n,n_squared;
for(n=n_squared=0;n<100;n_squared+=n+ ++n)
printf("%i squared might or might not be %i\n",n,n_squared);
... doesn't always do what you think it will do. This can make debugging painful.
The reason is the ++n retrieves, modifies, and stores the value of n, which could be before or after n is retrieved. Therefore, the value of n_squared isn't clearly defined after the first iteration. Sequence points guarantee that the subexpressions are evaluated in order.