ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
The first function calls the second and provides as one of the arguments a long int that is, in this case, not a variable but is always 1. But instead of giving it simply "1" or "(long) 1" as I might have expected, it gives it "1L". My question is whether this is valid notation or not? Is it some sort of short hand for casting a int as a long int? Or is this nonsense?
It's a short hand to a cast, it means that the 1 passed won't be the default for a constant, which is the shortest form possible. 1 would be more likely a short or int, and not a long.
The first function calls the second and provides as one of the arguments a long int that is, in this case, not a variable but is always 1. But instead of giving it simply "1" or "(long) 1" as I might have expected, it gives it "1L". My question is whether this is valid notation or not?
It is valid.
Quote:
Is it some sort of short hand for casting a int as a long int?
No. It is the syntax for a long int constant.
1 is an int. If the expected data type were predeclared before the call, then I think the compiler would cast it to long.
(long)1 casts an int 1 to long.
1L is a long constant. It is not an int constant cast to long.
The difference between (long)1 and 1L is pretty subtle. Optimized code and maybe even unoptimized code should be the same. The result should certainly be the same. Depending on the predeclaration of the called function, even 1 might give the same answer.
For contrast consider (long)5000000000 vs. 5000000000L
5000000000 is an int that happens to equal 705032704 (on most common architectures), so (long)5000000000 is a long that equals 705032704. While 5000000000L is a long that, on X86_64 and other architectures with 64 bit long, equals 5000000000.
Since it is legacy code, it doesn't seem likely it was written for an architecture with 32 bit ints and 64 bit longs. X86 has 32 bit longs. Could it be from an architecture with 16 bit ints? Most times I've seen code like that it was written by someone lacking any clear understanding of when you might want a long vs. an int and getting away with bad mixtures because they're the same size on X86. So you might need to be careful of that.
1 is an int. If the expected data type were predeclared before the call, then I think the compiler would cast it to long.
(long)1 casts an int 1 to long.
1L is a long constant. It is not an int constant cast to long.
The difference between (long)1 and 1L is pretty subtle. Optimized code and maybe even unoptimized code should be the same. The result should certainly be the same. Depending on the predeclaration of the called function, even 1 might give the same answer.
For contrast consider (long)5000000000 vs. 5000000000L
5000000000 is an int that happens to equal 705032704 (on most common architectures), so (long)5000000000 is a long that equals 705032704. While 5000000000L is a long that, on X86_64 and other architectures with 64 bit long, equals 5000000000.
Since it is legacy code, it doesn't seem likely it was written for an architecture with 32 bit ints and 64 bit longs. X86 has 32 bit longs. Could it be from an architecture with 16 bit ints? Most times I've seen code like that it was written by someone lacking any clear understanding of when you might want a long vs. an int and getting away with bad mixtures because they're the same size on X86. So you might need to be careful of that.
Thanks to both of you for your answers.
This code is probably early 90s and I'm not sure what that means in terms of the machines it was designed for. The reason I was suspicious of it was the mix of usages, sometimes just 1 is passed and sometimes 1L. From the context a long is probably better. Hence I think if I correct all the 1s to 1Ls then I should be OK? I doubt this is causing any of the bugs I'm chasing but it's good to rule it out (and learn something).
P.s. If you're interested,
The function in question is a wrapper for an MPI call that collects the maximum value of a variable over all the processors. In some cases it is dealing with an array and giving the maximum values of each element (stored in an array the same size as the original) and in other cases it is just a single integer (often the "status" variable, which gets the fail/success value of a function call). The long value in question tells the function how many elements there are. I don't see any problem with using a hard-coded constant in this context but since we want a flexible function (that might have to work on old systems I guess) it makes sense to keep it general. Hence the need for a long.
Also hence the debugging pain, parallel debugging's not good!
This code is probably early 90s and I'm not sure what that means in terms of the machines it was designed for.
Take a look at the pointer variables. On 16-bit PCs, there were two types of pointers: "near" pointers were restricted to a 64K memory segment and "far" pointers could point anywhere. If you see vestiges of this distinction (such as the "p" vs. "lp" naming convention), then it was designed for a 16-bit system. Otherwise, it was probably designed for a 32-bit system.
In either case, "long" was probably 32 bits: 64-bit integers were uncommon then.
1 is an int. If the expected data type were predeclared before the call, then I think the compiler would cast it to long.
(long)1 casts an int 1 to long.
1L is a long constant. It is not an int constant cast to long.
The difference between (long)1 and 1L is pretty subtle. Optimized code and maybe even unoptimized code should be the same. The result should certainly be the same. Depending on the predeclaration of the called function, even 1 might give the same answer.
For contrast consider (long)5000000000 vs. 5000000000L
5000000000 is an int that happens to equal 705032704 (on most common architectures), so (long)5000000000 is a long that equals 705032704. While 5000000000L is a long that, on X86_64 and other architectures with 64 bit long, equals 5000000000.
Thanks for the refinement - I hadn't really appreciated the difference due to the fact that I've only touched on an object like this once before. I appreciate the correction, and have noted it
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339
Rep:
Quote:
The first function calls the second and provides as one of the arguments a long int that is, in this case, not a variable but is always 1. But instead of giving it simply "1" or "(long) 1" as I might have expected, it gives it "1L". My question is whether this is valid notation or not? Is it some sort of short hand for casting a int as a long int? Or is this nonsense?
Thanks very much!
Basically the same as ((long)1).
It works for f for float and u for unsigned too.
Quote:
1 is an int. If the expected data type were predeclared before the call, then I think the compiler would cast it to long.
(long)1 casts an int 1 to long.
1L is a long constant. It is not an int constant cast to long.
The difference between (long)1 and 1L is pretty subtle. Optimized code and maybe even unoptimized code should be the same. The result should certainly be the same. Depending on the predeclaration of the called function, even 1 might give the same answer.
For contrast consider (long)5000000000 vs. 5000000000L
5000000000 is an int that happens to equal 705032704 (on most common architectures), so (long)5000000000 is a long that equals 705032704. While 5000000000L is a long that, on X86_64 and other architectures with 64 bit long, equals 5000000000.
Since it is legacy code, it doesn't seem likely it was written for an architecture with 32 bit ints and 64 bit longs. X86 has 32 bit longs. Could it be from an architecture with 16 bit ints? Most times I've seen code like that it was written by someone lacking any clear understanding of when you might want a long vs. an int and getting away with bad mixtures because they're the same size on X86. So you might need to be careful of that.
I do not think this is true for 16bit little endian machines.
Quote:
Take a look at the pointer variables. On 16-bit PCs, there were two types of pointers: "near" pointers were restricted to a 64K memory segment and "far" pointers could point anywhere.
anywhere within the first megabyte
Quote:
If you see vestiges of this distinction (such as the "p" vs. "lp" naming convention), then it was designed for a 16-bit system. Otherwise, it was probably designed for a 32-bit system.
In either case, "long" was probably 32 bits: 64-bit integers were uncommon then.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.