LinuxQuestions.org
Latest LQ Deal: Latest LQ Deals
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-23-2009, 01:49 PM   #1
corp1126
LQ Newbie
 
Registered: Nov 2009
Posts: 4

Rep: Reputation: 0
C typedef notation.


Hi all,

I'm working with some legacy C code and am unsure about some notation I'm seeing. I essentially have the situation below,

Code:
void func_A(stuff)
{
    //Stuff

    func_B(x,1L);

    //More stuff
}

void func_B(int *n,long x)
{
    //Stuff
}
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!
 
Old 11-23-2009, 02:05 PM   #2
MBybee
Member
 
Registered: Jan 2009
Location: wherever I can make a living
Distribution: OpenBSD / Debian / Ubuntu / Win7 / OpenVMS
Posts: 440

Rep: Reputation: 57
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.

I'm not a big fan of passing a hardcoded constant like that, but to each their own, I suppose.
http://www.falvotech.com/content/pub...d-enumerations
http://people.msoe.edu/tritt/cpplang.html#suffixes

Last edited by MBybee; 11-23-2009 at 02:06 PM. Reason: clarity
 
Old 11-23-2009, 03:29 PM   #3
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by corp1126 View Post
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.

Last edited by johnsfine; 11-23-2009 at 03:56 PM.
 
Old 11-23-2009, 04:36 PM   #4
corp1126
LQ Newbie
 
Registered: Nov 2009
Posts: 4

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by johnsfine View Post
It is valid.



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.
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!
 
Old 11-23-2009, 05:59 PM   #5
Dan04
Member
 
Registered: Jun 2006
Location: Texas
Distribution: Ubuntu
Posts: 207

Rep: Reputation: 37
Quote:
Originally Posted by corp1126 View Post
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.
 
Old 11-24-2009, 08:53 AM   #6
MBybee
Member
 
Registered: Jan 2009
Location: wherever I can make a living
Distribution: OpenBSD / Debian / Ubuntu / Win7 / OpenVMS
Posts: 440

Rep: Reputation: 57
Thumbs up

Quote:
Originally Posted by johnsfine View Post
It is valid.

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.
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
 
Old 11-24-2009, 10:40 AM   #7
smeezekitty
Senior Member
 
Registered: Sep 2009
Location: Washington U.S.
Distribution: M$ Windows / Debian / Ubuntu / DSL / many others
Posts: 2,339

Rep: Reputation: 231Reputation: 231Reputation: 231
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.
Dont work on turbo C++
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
typedef in C Oaks Programming 1 08-05-2009 09:49 AM
[C] The FAR in typedef koyi Programming 2 07-21-2006 07:37 PM
having problem with typedef TurtleFace Programming 4 03-30-2006 09:18 PM
pointer notation vs array notation? pablowablo Programming 5 03-14-2005 12:34 PM
Can you help me with typedef? brownstone Programming 3 06-11-2004 10:09 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:39 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration