Long Long In C99 - Stack Overflow
-
- Home
- Questions
- Tags
- Users
- Companies
- Labs
- Jobs
- Discussions
- Collectives
-
Communities for your favorite technologies. Explore all Collectives
- Teams
Ask questions, find answers and collaborate at work with Stack Overflow for Teams.
Try Teams for free Explore Teams - Teams
-
Ask questions, find answers and collaborate at work with Stack Overflow for Teams. Explore Teams
Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about CollectivesTeams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about TeamsGet early access and see previews of new features.
Learn more about Labs Long long in c99 Ask Question Asked 3 years, 10 months ago Modified 3 years, 10 months ago Viewed 2k times 8In the C99 standard they introduced long long. What is the purpose of this? In my (limited) C programming experience, I've only every seen a 4-byte int and an 8-byte long. For example, from Compiler Explorer:
If long is already 8 then, why is it necessary to add another long long type? What does this do to the compiler/architecture?
Share Improve this question Follow edited Jan 10, 2021 at 3:06 Peter Cordes 360k49 gold badges695 silver badges956 bronze badges asked Jan 9, 2021 at 22:20 carl.hiasscarl.hiass 1,7541 gold badge13 silver badges42 bronze badges 16- 2 8-byte long was not the norm in those days; 4-byte long was more common on 16- and 32-bit platforms (and still is). Of course 64-bit machines were rare in 1999. – Nate Eldredge Commented Jan 9, 2021 at 22:27
- 2 long is 4 bytes in Visual C and 8 in gcc and for that reason I never use it. – Weather Vane Commented Jan 9, 2021 at 22:34
- 2 @carl.hiass well, long long clearly. – fuz Commented Jan 9, 2021 at 22:44
- 2 @WeatherVane It is down to the platform, not the compiler. On Windows a long is 32bit even in gcc (assuming the native MinGW rather then Cygwin version that is). en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models – Clifford Commented Jan 9, 2021 at 23:02
- 2 @prl How does introducing long long break compatibility given code bases up to then did not have long long? Not being the widest integer type? I certainly see how requiring long as 64-bit would break things. – chux Commented Jan 9, 2021 at 23:25
5 Answers
Sorted by: Reset to default Highest score (default) Trending (recent votes count more) Date modified (newest first) Date created (oldest first) 6If long is already 8 then, why is it necessary to add another long long type? What does this do to the compiler/architecture?
"If long is already 8" is not always true as much code exists that relies on 32-bit long and int as 32 or 16 bits.
Requiring long as 64-bit would break code bases. This is a major concern.
Yet requiring long to remain 32-bit (and no long long) would not make for access to standard 64-bit integers, hence a rationale for long long.
Allowing long as either 32-bit or 64-bit (or others) allows for transition.
Various functions pass in/return long like fseek(), ftell(). They benefit from long being more than 32-bit for large file support.
Recommended practice encourages a wider long: "The types used for size_t and ptrdiff_t should not have an integer conversion rank greater than that of signed long int unless the implementation supports objects large enough to make this necessary." This relates to memory sizes exceeding 32-bit.
Perhaps in the future an implementation may use int/long/long long/intmax_t as 32/64/128/256 bits.
IAC, I see fixed width types intN_t increasing in popularity over long and long long. I tend to use fixed width types or bool, (unsigned) char, int/unsigned, size_t, (u)intmax_t and leave signed char, (unsigned) short, (unsigned) long, (unsigned) long long for special cases.
Share Improve this answer Follow edited Jan 25, 2021 at 7:44 Alex Reinking 19.6k7 gold badges64 silver badges104 bronze badges answered Jan 9, 2021 at 22:36 chuxchux 153k15 gold badges144 silver badges285 bronze badges 3- do any programs still run on 16-bit machines today? – carl.hiass Commented Jan 9, 2021 at 22:39
- 2 @carl.hiass Oh yes. Billions of embedded processes are made each year. A large share are 8/16-bit typically compiled with 16-bit int. – chux Commented Jan 9, 2021 at 22:43
- @carl.hiass even 8-bit microcontrollers are still wildly common. They exist in lost of places where you don't realize like in your refrigerators, microwaves, speakers, home controllers, clocks, mice, keyboards, remote controls... There are even "odd" MCUs like 20, 24 or 28 or 48-bit ones for audio processing – phuclv Commented Jan 10, 2021 at 6:59
The C standard only guarantees that an int can be (loosely speaking) 2 bytes, a long can be 4 bytes, and a long long can be 8 bytes.
In fact, MSVC still uses a 4 byte long even though it has a 4 byte int.
Share Improve this answer Follow answered Jan 9, 2021 at 22:26 dbushdbush 221k24 gold badges238 silver badges308 bronze badges 4- 1 long doesn't seem to have a place – you could have said "gcc uses an 8-byte long even though it has long long". – Weather Vane Commented Jan 9, 2021 at 22:37
- @WeatherVane No, you can't say that. Because it has nothing to do with gcc. The size of a long on Linux is specified by the ABI, not gcc. On Windows, the size of a long in 64-bit executables is 4 bytes whether the compiler is gcc or MSVC. – Andrew Henle Commented Jan 9, 2021 at 22:49
- 1 @AndrewHenle thanks - but my point still applies, with a little rephrasing. – Weather Vane Commented Jan 9, 2021 at 22:55
- It is not MSVC++ specific, that is the WIn64 data model en.wikipedia.org/wiki/64-bit_computing#64-bit_data_models – Clifford Commented Jan 9, 2021 at 23:06
The only relevant requirement for int and long, then and now, is that int must be at least 16 bits and long must be at least 32 bits. 16- and 32-bit systems both tend to have 32-bit long, and 64-bit machines were much less common in the late 1990s. So prior to C99, programmers could not portably rely on having a 64-bit integer type available at all. That problem was solved by the introduction of long long, which is required to be at least 64 bits. (I believe it was already provided by GCC and maybe other compilers as an extension).
These days, many (but not all) 64-bit systems use a 64-bit long and do not bother to make long long any bigger, so it is 64 bits as well and is in some sense redundant. Those are presumably the systems with which you're familiar, but they do not represent everything out there.
Share Improve this answer Follow answered Jan 9, 2021 at 22:38 Nate EldredgeNate Eldredge 56.3k6 gold badges66 silver badges105 bronze badges Add a comment | 2I think you didn't realize that you're making a huge wrong assumption about how C type-width requirements work: ISO C just sets a minimum value-range like the smallest-magnitude allowed LONG_MAX and LONG_MIN (-2147483647, not 8 because ISO C allows one's complement and sign/magnitude signed integers, not only 2's complement.) Actual implementations are allowed to have wider types, often to match a register width or operand-size the target machine can do efficiently.
Much has been written about this on Stack Overflow and elsewhere, which I'm not going to try to repeat here. See also https://en.cppreference.com/w/c/language/arithmetic_types
That led you to the mistake of looking at the type-width choices in the x86-64 System V ABI and assuming that other C implementations are the same, I think. x86-64 is a 64-bit ISA that can efficiently work with 64-bit integers, so 64-bit long was a fairly sane choice.
No sane ABI for a 32-bit machine like i386 would use 64-bit long because that's not required, only 32-bit. Using 64-bit would mean it couldn't fit into a single register. Compile with -m32, or compile for 32-bit ARM. Godbolt also has GCC for AVR and MSP430. On those 8-bit and 16-bit machines, GCC picks the smallest widths allowed by ISO C (2-byte int, etc.)
In 1999, x86-64 didn't even exist. (A few other 64-bit ISAs did, like Alpha). So looking at one of the 2 mainstream ABIs for it to understand C99 choices is not going to get you very far.
Of course C needs a type that's guaranteed to be at least 64-bit, to let people write programs that efficiently do 64-bit integer math.
And BTW, x86-64 can do 32-bit integer stuff as efficiently as 64-bit, sometimes more efficiently. So making long a 64-bit type is arguably not great. Some code uses long because they want a type that needs to be 32-bit, but doesn't benefit from having it wider. For such code, 64-bit long just wastes cache footprint / memory bandwidth, and code size (REX prefixes). In C99 the ideal choice would be int_least32_t, but that's annoyingly long to type and rarely used.
But OTOH, long is sometimes hoped to be "the widest efficient (1-register) type", although there's no such guarantee and LLP64 ABIs like Windows x64 with 32-bit long aren't like that.
Another whole can of worms is C99 int_fast32_t and x86-64 System V's IMO poor choice to make that a 64-bit type. (I have a half-written answer for Cpp uint32_fast_t resolves to uint64_t but is slower for nearly all operations than a uint32_t (x86_64). Why does it resolve to uint64_t? which I should finish... int_fast32_t raises the question of "fast for what purpose", and on many implementations it's not what you'd hope for many cases.
See also
- C++ - the fastest integer type?
- How should the [u]int_fastN_t types be defined for x86_64, with or without the x32 ABI?
- Why would uint32_t be preferred rather than uint_fast32_t?
- Why is uint_least16_t faster than uint_fast16_t for multiplication in x86_64?
- Compiler optimizations allowed via "int", "least" and "fast" non-fixed width types C/C++
There are some limits but the compiler author is free to choose the lengths for the standard C variable types (char, short, int, long, long long). Naturally char is going to be a byte for that architecture (most with C compilers are 8 bits). And naturally you cannot have something smaller be bigger than something bigger, long cannot be smaller than an int. But certainly by 1999 we saw the x86 16 to 32 bit transition and for example int changed from 16 to 32 with a number of tools but long stayed 32. Later the 32 to 64 bit x86 transition happened and depending on the tool there were types available to help.
The problem existed long before this and the solution was not to fix the lengths of the types, they are, within rules, up to the compiler authors as to size. But the compiler authors need to craft a stdint.h file that matches the tool and target (stdint.h is specific to a tool and target at a minimum and can be version of tool and build options for that tool, etc). So that, for example, uint32_t is always 32 bits. Some authors will convert that to an int others a long, etc in their stdint.h. The C language variable types remain limited to char, short, int, etc per the language (uint32_t is not a variable type it is converted to a variable type through stdint.h). This solution/workaround was a way to keep is from all going crazy and keep the language alive.
Authors will often choose for example if the GPRs are 16 bit to have int be 16 bit, and if 32 bit be 32 bit and so on, but they have some freedom.
Yes, this specifically means that there is no reason to assume that any two tools for a particular target (the computer you are reading this on for example) use the same definitions for int and long in particular, and if you want to write code for this platform that can port across these tools (that support this platform) then use the stdint.h types and not int, long, etc...Most certainly if you are crossing platforms an msp430 mcu, an arm mcu, an arm linux machine, an x86 based machine, that the types, even for the same "toolchain" (gnu gcc and binutils for example), do not have the same definitions for int and long, etc. char and short tend to be 8 and 16 bits, int and long tend to vary the most, sometimes the same size as each other sometimes different, but the point is do not assume.
It is trivial to detect the sizes, for a compiler version/target/command line options, or just go the stdint route to minimize problems later.
Share Improve this answer Follow answered Jan 10, 2021 at 23:16 old_timerold_timer 71.2k9 gold badges98 silver badges173 bronze badges Add a comment |Your Answer
Reminder: Answers generated by artificial intelligence tools are not allowed on Stack Overflow. Learn more
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Draft saved Draft discardedSign up or log in
Sign up using Google Sign up using Email and Password SubmitPost as a guest
Name EmailRequired, but never shown
Post Your Answer DiscardBy clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.
Not the answer you're looking for? Browse other questions tagged
or ask your own question.- The Overflow Blog
- Your docs are your infrastructure
- Featured on Meta
- More network sites to see advertising test [updated with phase 2]
- We’re (finally!) going to the cloud!
Linked
88 Why would uint32_t be preferred rather than uint_fast32_t? 27 sizeof(long) in 64-bit Windows 12 Why is uint_least16_t faster than uint_fast16_t for multiplication in x86_64? 8 C++ - the fastest integer type? 3 Compiler optimizations allowed via "int", "least" and "fast" non-fixed width types C/C++ 6 How should the [u]int_fastN_t types be defined for x86_64, with or without the x32 ABI? 3 Cpp uint32_fast_t resolves to uint64_t but is slower for nearly all operations than a uint32_t (x86_64). Why does it resolve to uint64_t?Related
3 Is the type "long long" always 64 bits? 8 C: long long always 64 bit? 3 long long in C++ 0 x86 assembly short and long size 2 ".long ." What does it mean in arm assembly coding? 0 Long long is 8 bytes, meaning? 5 Size of "long long" in 128-bit machine? 0 C datatype 'long'- on Intel x86 64-bit machine 3 Understanding assembly .long directive 0 Enabling long long in C89 at GCC 3.2, 4.4 and 5.4Hot Network Questions
- Implicit function theorem without manifolds (Steve Smale article)?
- Use of “12 m.” for noon and “12 p.m.” for midnight
- will "brown aluminum" drip-edge suffer galvanic corrosion if it rests against fascia made of copper-treated lumber?
- Using Revese Tunnel to for accessing URL not directly accessible
- How is one supposed to play these notes?
- Should I ask for physical recommendation letters now to avoid future issues with professors' availability?
- Irregularities in Moment of inertia of torus
- Correct place to store data required for custom addon
- range has lost one leg of 220
- How do I report to Springer a scientific fraud to a cryptographic paper published in Springer?
- Converting Line Segments to Lines
- How to connect via SSH through multiple hosts, each of the intermediate hosts only accepting keys from the first host?
- Most Efficient Glide: Pitch Up or Level Flight to Bleed Airspeed
- Can Martial Characters use Spell Scrolls in D&D 2024?
- Arrange 3 red balls and 33 white balls randomly in a circle. What is the probability that there are no more than 13 consecutive white balls?
- What is the proper way to say "voice direction" in German?
- Why is the chi-square test giving unintuitive results?
- Is the Heter for music on Shabbat universal
- Translating Russian "не то, не то" into English
- Are garbage-collection programming languages inherently unsafe for use in cryptography
- Did anything ever use the -12V line on the original PC power supply?
- Conditional Definition of a Mathematical Operator
- How to identify unsafe trees for climbing stand?
- When and how were nets and filters first shown to be equivalent?
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
lang-cTừ khóa » C99 Long
-
C Data Types - Wikipedia
-
Long - ARM Compiler V5.06 For UVision Armcc User Guide
-
C99 Support Of Long Long Data Type - IBM
-
C99
-
Fixed Width Integer Types (since C99)
-
C - Data Types - Tutorialspoint
-
Warning: Use Of C99 Long Long Integer Constant | C Programming
-
Long Long (Using The GNU Compiler Collection (GCC))
-
C/IntegerTypes
-
4.2.3 C99 Language Specifications Supported In Conjunction With C90
-
Integer Objects — Python 3.10.5 Documentation
-
C Programming Course Notes - Data Types