They haven't made it impossible, but they've made some very large barriers to entry. Amazon can afford to maintain replacements for all of the Google applications, and even its own app store. Few other companies can. Using Google-Android is a lot cheaper than using OHA-Android, because you don't have so much in-house development costs. Google doesn't want to prevent Apple dominance to avoid a monopoly, Google wants a monopoly in mobile phone software.
A socialist would believe that all of the workers who contributed to Oracle's success should be allowed to share in the results. A capitalist would believe that all of the investors whose capital made that success possible should share in that success. There are several terms for someone who thinks that the founder should be able to get all of the benefit because he's rich, but none of them are very polite.
Yes, although 15 years ago they'd probably have spec'd out a 64KB chip and then applied pressure to the software team to trim the code until it fitted in 64KB. But, yes, it's very common to have code that needs to be just over a power of two size and it's cheaper to buy the bigger chip than to to try to squeeze the code smaller. Especially for very small sizes (under about 4Mbit) the cost of the packaging is such a dominant factor in the code of the IC that you may not even be able to get the smaller chips for less money.
One of the more interesting bits of malware I've seen recently ran in the controller for USB keyboards. These things have 128KB of flash, of which about 10KB was free. That was enough for a keylogger that was triggered by certain stimuli (e.g. power just turned on, 'su' typed) to record short segments, and which would dump its buffer into a special USB device plugged into the USB hub on the back of the keyboard. You could install a load of them in an office somewhere and just have a cleaner come around and plug things into the backs as he went around the room.
For a decade or so, flash has been cheap enough to use as a replacement for ROM and the benefits are obvious to a hardware manufacturer. You can delay ROM programming until after final assembly, giving you a shorter time to market and you can do bug fixes in the field. Both of these mean that you want to have a bit more flash capacity than you actually need, because either you don't know the final firmware size when you spec the device, or you might want to add some features later.
Firewire yes. Firewire can muck around with system RAM directly.
Well, not exactly. It is possible to configure a FireWire controller's DMA access to have full access to the system RAM. Apple does this so that you can use an iPod to get crash dumps (then disables it because it's a security hole, then reopens it in the next release because sysadmins complain that they can't get crash dumps, then disables it because...). You'll typically have an IOMMU between the FireWire chip and the system RAM though, so it's possible for the host to restrict this access.
USB cannot it all has to go via the CPU.
Modern USB controllers also support DMA. If there's a bug in the controller firmware, then this could be exploited to allow device-initiated, rather than driver-initiated, DMA.
I work quite closely with various parts of the semiconductor industry, but I've not heard anyone say that Moore's law is dead. Transistors are still shrinking, the problem is not that the number of transistors you can stick on an IC is not changing, but that the number you can have powered at once is not dropping much. Each new generation in process technology reduces the size (or, at least, increases yields or reduces costs), but it only has a small impact on the power consumption per transistor. That is why people are talking about 'dark silicon' - you may be able to have 2-4 times as many transistors as a previous generation, but you can only use 1.2 or so times as many at once in the same power / heat budget. This makes a big difference to how you design chips - now you're focussing a lot more on things that accelerate specific applications, because things that give a big speedup sometimes but are unused most of the time are actually beneficial.
We've more or less harmonised VAT, which is equivalent of sales tax. It's not the same in every state, but it's slowly getting that way, and member states need EU permission to change it (as happened when the UK lowered it to 15% and then brought it up to 20%).
You're asking for the same thing, because you apparently don't understand how modern compilers work.
The deletion happens much later on in the compiler pipeline. By the time you get to this point, you've inlined the memcpy (because you've decided that copying 20 bytes is not worth a function call), and propagated the alias information out. The code consuming the alias information, and determining that you're doing something undefined is dealing with an intermediate representation that is no longer even slightly close to the source.
In this particular case, it's something you could probably do just by inspecting the AST, but most cases of code relying on undefined behaviour are only exposed to optimisation passes after you've done dominance frontier construction, inlining, function specialisation, constant propagation, common subexpression elimination and probably loop-invariant code motion. By the time you're in this state, telling the difference between something that is undefined behaviour that is exposed after a long chain of transforms, or something that the programmer intended is difficult, without maintaining a full back-mapping (want to see your compiler memory usage increase by a factor of 20?) for every transform.
And even if it does, all that tells you is that you're doing something wrong (or not - it may be intentional) that this particular compiler version is taking advantage of, it doesn't tell you what the next point release will do. You're better off running something like the clang static analyser that can do symbolic evaluation on functions and point to potentially undefined behaviour.
That should just work as intended, or at least give a compiler warning. Instead, the compiler just takes it out without warning because it thinks it knows better than us.
Quite the reverse. The compiler is assuming that you know what you mean and have written what you mean. If what you mean doesn't make sense, then it tries to interpret it as best as it can (in this example, if you've done something that means that the only well-defined values of i are 0-4, then i is always less than 10).
The problem is that most of these things need global analysis to see if they are as a result of undefined behaviour, but the optimisers only do local analysis.
If you really want that, then it will take significantly longer to compile your code than to run it. For example, consider something as simple as a memcpy(). It takes two pointer arguments, both of which are restrict-qualified. The compiler is therefore free to assume that they don't alias, because you have undefined behaviour of they do. But if you want to check this at compile time, then you need to first build a complete code flow graph of the entire program (including shared libraries) and then a data flow graph. You then have to prove that either the two values are different objects (even if they've been allocated a dozen calls up the stack, or both came from globals that were assigned a few thousand function invocations ago, in different calls), or that they're the same object but the offsets are different. Oh, and you have to also statically prove that the size of each object (counting from the pointers passed as arguments) is greater than or equal to the size passed as the third argument.
Now, it might just about be possible to compute some of these in the general case in finite time, but not all of them and I, for one, like having my compiler terminate.
-fsanitize=undefined will do it in clang. Any time there is potentially undefined behaviour, the compiler will branch to a handler. It generates slower code, but it's good for debugging.
Here's another one: ordered comparisons between pointers to different objects (less-than or greater-than). These are undefined in C and C++, and yet every STL implementation I've seen relies on them being both defined and stable for many collections (map, set and friends) to work. C++11 is explicitly written to allow implementations with GCs that modify pointer values, so this could cause some interesting issues in the future...
This is not correct, however there is a set of constraints in C and a set of constraints in POSIX which, when composed, mean that 8 bits is the only valid size for a char, so if you are writing C code that only targets POSIX machines then you can safely assume that char is 8 bits.
I have never seen a compiler that does that, and I seriously doubt if is really common. Does anyone know of a single compiler that does this?
The only compilers I know of that definitely do this are GCC, LLVM, ICC, Open64, ARMCC, and XLC, but others probably do too. Compilers use undefined behaviour to propagate unreachable state and aggressively trim code paths. There's a fun case in ARM's compiler, where you write something like this:
int x[5]; int y; ... for (int i=0 ; i<10 ; i++) y += x[i];
The entire loop is optimised away to an infinite loop. Why? Because accesses to array elements after the end of the array are undefined. This means that, when you write x[i] then either i is in the range 0-4 (inclusive), or you are hitting undefined behaviour. Because the compiler can do anything it wants in cases of undefined behaviour, it is free to assume that they never occur. Therefore, it assumes that, at the end of the loop, i is always less than 5. Therefore, i++ is always less than 10, and therefore the loop will never terminate. Therefore, since the body of the loop has no side effects, it can be elided. Therefore, the declarations of x and y are never read from in anything with side effects and so can be elided. Therefore, the entire function becomes a single branch instruction that just jumps back to itself.
If your code relies on undefined behaviour, then it's broken. A compiler is entirely free to do whatever it wants in the cases where the behaviour is undefined. Checking for undefined behaviour statically is very hard, however (consider trying to check for correct use of the restrict keyword - you need to do accurate alias analysis on the entire program) and so compilers won't warn you in all cases. Often, the undefined behaviour is only apparent after inlining, at which point it's difficult to tell what the source of the problem was.
Does Firefox on Android now implement fine-grained cookie control, or is it still limited to the same thing as Chrome and the Android Browser (accept all, deny all)?
On other platforms, this is solved by nspluginwrapper, which runs the plugin as a separate process and just sends events and screen contents between them. Given that most web browsers now do something similar for security and stability (so a plugin can't crash the browser and a security problem in the plugin is isolated), it's not likely to be a significant issue.
It's disingenuous to count from the time XP first shipped. The important dates are when it stopped being shipped, and when an adequate replacement was available from the supplier. New machines were still being shipped with XP until very recently, especially in the low-end laptop market. If you count Vista as an adequate replacement, it shipped in January 2007. If you count Windows 7, which was the one that persuaded a lot of people to upgrade, then that's only 4 years old, which is still within a corporate upgrade cycle.
The other two important dates are when the last major update was released (5 years ago) and when security releases stop (next year).
That said, if you're planning on using an OS after it stops getting security patches, you'd better be sure that it's not connected to a network, which somewhat limits the utility of a web browser...
Boris Johnson has always been popular. He's a very intelligent individual who plays the affable buffoon role to perfection and so seems unthreatening. However, polls asking whether he'd make a good prime minister have consistently shown a lot less support than ones just judging his popularity. This may change as a result of his time as Mayor of London, but it would still be a big gamble for the Conservatives.
If you want to fix the problem, it's important to understand the cause. If the problem is the institution, not the individual, then attacking the individual won't solve it.
I know a number of freelance copyeditors who will do a good job on a scientific paper and charge a few tens of dollars. It's a pretty cutthroat market, and you can probably find cheaper ones, but these are ones that I've worked with and would recommend. $28k for 24 papers works out at over $1100 per paper - I can get entire books copyedited by very competent people for less than that. Actually, the same is true for layout. For a lot of journals, you just use an existing LaTeX template and don't do any more layout. The ones that do more advanced compositing are typically funded elsewhere (e.g. conference fees).
Most conferences and journals that I've sent work to allow the author to put the pre-print on their own web site. These doesn't have spelling corrections or the journal's formatting, but they have all of the content. It always annoys me when academics don't take advantage of this.
I'm not sure if it's the same in medicine, but since it's often the same publishers I wouldn't be surprised if it is.
That's a crazy misrepresentation. The Phoronix article is mentioning the fact that clang now enables the autovectorisers at -O2, but it doesn't cover the reason for the switch. -O2 is intended as the default optimisation level for release builds. It should (almost) always produce faster code than -O1 or -O0, at the cost of greater compile times. Enabling an optimisation at that level means that it's unlikely to cause slowdowns. In 3.3 and in GCC, the autovectoriser can create larger code and more vector-scalar register copies that cause a slowdown that offsets the speedup from using the vector ALUs. As such, they're only run if explicitly enabled, so you people with performance-critical code can test them and see if they actually do provide a speedup.
As to the quality of the error messages, I recently fixed a number of bugs in some third party code that were raising warnings with clang. One warning, that a comparison was the result of a comparing an unsigned value as being less than zero, occurred in four string processing loops in the code. In each case, it was iterating over characters in a user-provided string and appeared to be a security hole. Fixing it was trivial (change the type to a signed integer), but I like it when my compiler points out serious bugs in code that I'm compiling.
The above post was correctly marked as flamebait, but there's a grain of truth in it. ICC, for example, still does a much better job at vectorisation than gcc or clang (clang with polly enabled does about as well, significantly better in some cases). The autoparallelisation stuff in the Sun, uh, Oracle, compiler is also pretty impressive on certain workloads.
They haven't made it impossible, but they've made some very large barriers to entry. Amazon can afford to maintain replacements for all of the Google applications, and even its own app store. Few other companies can. Using Google-Android is a lot cheaper than using OHA-Android, because you don't have so much in-house development costs. Google doesn't want to prevent Apple dominance to avoid a monopoly, Google wants a monopoly in mobile phone software.
A socialist would believe that all of the workers who contributed to Oracle's success should be allowed to share in the results. A capitalist would believe that all of the investors whose capital made that success possible should share in that success. There are several terms for someone who thinks that the founder should be able to get all of the benefit because he's rich, but none of them are very polite.
Yes, although 15 years ago they'd probably have spec'd out a 64KB chip and then applied pressure to the software team to trim the code until it fitted in 64KB. But, yes, it's very common to have code that needs to be just over a power of two size and it's cheaper to buy the bigger chip than to to try to squeeze the code smaller. Especially for very small sizes (under about 4Mbit) the cost of the packaging is such a dominant factor in the code of the IC that you may not even be able to get the smaller chips for less money.
From the list of things I learned in the '80s: don't use the fast dubbing mode to copy games.
One of the more interesting bits of malware I've seen recently ran in the controller for USB keyboards. These things have 128KB of flash, of which about 10KB was free. That was enough for a keylogger that was triggered by certain stimuli (e.g. power just turned on, 'su' typed) to record short segments, and which would dump its buffer into a special USB device plugged into the USB hub on the back of the keyboard. You could install a load of them in an office somewhere and just have a cleaner come around and plug things into the backs as he went around the room.
For a decade or so, flash has been cheap enough to use as a replacement for ROM and the benefits are obvious to a hardware manufacturer. You can delay ROM programming until after final assembly, giving you a shorter time to market and you can do bug fixes in the field. Both of these mean that you want to have a bit more flash capacity than you actually need, because either you don't know the final firmware size when you spec the device, or you might want to add some features later.
Firewire yes. Firewire can muck around with system RAM directly.
Well, not exactly. It is possible to configure a FireWire controller's DMA access to have full access to the system RAM. Apple does this so that you can use an iPod to get crash dumps (then disables it because it's a security hole, then reopens it in the next release because sysadmins complain that they can't get crash dumps, then disables it because...). You'll typically have an IOMMU between the FireWire chip and the system RAM though, so it's possible for the host to restrict this access.
USB cannot it all has to go via the CPU.
Modern USB controllers also support DMA. If there's a bug in the controller firmware, then this could be exploited to allow device-initiated, rather than driver-initiated, DMA.
I work quite closely with various parts of the semiconductor industry, but I've not heard anyone say that Moore's law is dead. Transistors are still shrinking, the problem is not that the number of transistors you can stick on an IC is not changing, but that the number you can have powered at once is not dropping much. Each new generation in process technology reduces the size (or, at least, increases yields or reduces costs), but it only has a small impact on the power consumption per transistor. That is why people are talking about 'dark silicon' - you may be able to have 2-4 times as many transistors as a previous generation, but you can only use 1.2 or so times as many at once in the same power / heat budget. This makes a big difference to how you design chips - now you're focussing a lot more on things that accelerate specific applications, because things that give a big speedup sometimes but are unused most of the time are actually beneficial.
We've more or less harmonised VAT, which is equivalent of sales tax. It's not the same in every state, but it's slowly getting that way, and member states need EU permission to change it (as happened when the UK lowered it to 15% and then brought it up to 20%).
You're asking for the same thing, because you apparently don't understand how modern compilers work.
The deletion happens much later on in the compiler pipeline. By the time you get to this point, you've inlined the memcpy (because you've decided that copying 20 bytes is not worth a function call), and propagated the alias information out. The code consuming the alias information, and determining that you're doing something undefined is dealing with an intermediate representation that is no longer even slightly close to the source.
In this particular case, it's something you could probably do just by inspecting the AST, but most cases of code relying on undefined behaviour are only exposed to optimisation passes after you've done dominance frontier construction, inlining, function specialisation, constant propagation, common subexpression elimination and probably loop-invariant code motion. By the time you're in this state, telling the difference between something that is undefined behaviour that is exposed after a long chain of transforms, or something that the programmer intended is difficult, without maintaining a full back-mapping (want to see your compiler memory usage increase by a factor of 20?) for every transform.
And even if it does, all that tells you is that you're doing something wrong (or not - it may be intentional) that this particular compiler version is taking advantage of, it doesn't tell you what the next point release will do. You're better off running something like the clang static analyser that can do symbolic evaluation on functions and point to potentially undefined behaviour.
That should just work as intended, or at least give a compiler warning. Instead, the compiler just takes it out without warning because it thinks it knows better than us.
Quite the reverse. The compiler is assuming that you know what you mean and have written what you mean. If what you mean doesn't make sense, then it tries to interpret it as best as it can (in this example, if you've done something that means that the only well-defined values of i are 0-4, then i is always less than 10).
The problem is that most of these things need global analysis to see if they are as a result of undefined behaviour, but the optimisers only do local analysis.
If you really want that, then it will take significantly longer to compile your code than to run it. For example, consider something as simple as a memcpy(). It takes two pointer arguments, both of which are restrict-qualified. The compiler is therefore free to assume that they don't alias, because you have undefined behaviour of they do. But if you want to check this at compile time, then you need to first build a complete code flow graph of the entire program (including shared libraries) and then a data flow graph. You then have to prove that either the two values are different objects (even if they've been allocated a dozen calls up the stack, or both came from globals that were assigned a few thousand function invocations ago, in different calls), or that they're the same object but the offsets are different. Oh, and you have to also statically prove that the size of each object (counting from the pointers passed as arguments) is greater than or equal to the size passed as the third argument.
Now, it might just about be possible to compute some of these in the general case in finite time, but not all of them and I, for one, like having my compiler terminate.
-fsanitize=undefined will do it in clang. Any time there is potentially undefined behaviour, the compiler will branch to a handler. It generates slower code, but it's good for debugging.
Here's another one: ordered comparisons between pointers to different objects (less-than or greater-than). These are undefined in C and C++, and yet every STL implementation I've seen relies on them being both defined and stable for many collections (map, set and friends) to work. C++11 is explicitly written to allow implementations with GCs that modify pointer values, so this could cause some interesting issues in the future...
This is not correct, however there is a set of constraints in C and a set of constraints in POSIX which, when composed, mean that 8 bits is the only valid size for a char, so if you are writing C code that only targets POSIX machines then you can safely assume that char is 8 bits.
I have never seen a compiler that does that, and I seriously doubt if is really common. Does anyone know of a single compiler that does this?
The only compilers I know of that definitely do this are GCC, LLVM, ICC, Open64, ARMCC, and XLC, but others probably do too. Compilers use undefined behaviour to propagate unreachable state and aggressively trim code paths. There's a fun case in ARM's compiler, where you write something like this:
The entire loop is optimised away to an infinite loop. Why? Because accesses to array elements after the end of the array are undefined. This means that, when you write x[i] then either i is in the range 0-4 (inclusive), or you are hitting undefined behaviour. Because the compiler can do anything it wants in cases of undefined behaviour, it is free to assume that they never occur. Therefore, it assumes that, at the end of the loop, i is always less than 5. Therefore, i++ is always less than 10, and therefore the loop will never terminate. Therefore, since the body of the loop has no side effects, it can be elided. Therefore, the declarations of x and y are never read from in anything with side effects and so can be elided. Therefore, the entire function becomes a single branch instruction that just jumps back to itself.
If your code relies on undefined behaviour, then it's broken. A compiler is entirely free to do whatever it wants in the cases where the behaviour is undefined. Checking for undefined behaviour statically is very hard, however (consider trying to check for correct use of the restrict keyword - you need to do accurate alias analysis on the entire program) and so compilers won't warn you in all cases. Often, the undefined behaviour is only apparent after inlining, at which point it's difficult to tell what the source of the problem was.
Does Firefox on Android now implement fine-grained cookie control, or is it still limited to the same thing as Chrome and the Android Browser (accept all, deny all)?
On other platforms, this is solved by nspluginwrapper, which runs the plugin as a separate process and just sends events and screen contents between them. Given that most web browsers now do something similar for security and stability (so a plugin can't crash the browser and a security problem in the plugin is isolated), it's not likely to be a significant issue.
That said, if you're planning on using an OS after it stops getting security patches, you'd better be sure that it's not connected to a network, which somewhat limits the utility of a web browser...
Boris Johnson has always been popular. He's a very intelligent individual who plays the affable buffoon role to perfection and so seems unthreatening. However, polls asking whether he'd make a good prime minister have consistently shown a lot less support than ones just judging his popularity. This may change as a result of his time as Mayor of London, but it would still be a big gamble for the Conservatives.
- that's something the security services would wish to trumpet to the skies, especially now, and
Not if it would prevent prosecution.
- we can check and see if any accused terrorists were pulled over at a traffic stop (or something equally bland)
People have done already, and there are a lot of things that look like this is at least possible.
If you want to fix the problem, it's important to understand the cause. If the problem is the institution, not the individual, then attacking the individual won't solve it.
I know a number of freelance copyeditors who will do a good job on a scientific paper and charge a few tens of dollars. It's a pretty cutthroat market, and you can probably find cheaper ones, but these are ones that I've worked with and would recommend. $28k for 24 papers works out at over $1100 per paper - I can get entire books copyedited by very competent people for less than that. Actually, the same is true for layout. For a lot of journals, you just use an existing LaTeX template and don't do any more layout. The ones that do more advanced compositing are typically funded elsewhere (e.g. conference fees).
Most conferences and journals that I've sent work to allow the author to put the pre-print on their own web site. These doesn't have spelling corrections or the journal's formatting, but they have all of the content. It always annoys me when academics don't take advantage of this. I'm not sure if it's the same in medicine, but since it's often the same publishers I wouldn't be surprised if it is.
As to the quality of the error messages, I recently fixed a number of bugs in some third party code that were raising warnings with clang. One warning, that a comparison was the result of a comparing an unsigned value as being less than zero, occurred in four string processing loops in the code. In each case, it was iterating over characters in a user-provided string and appeared to be a security hole. Fixing it was trivial (change the type to a signed integer), but I like it when my compiler points out serious bugs in code that I'm compiling.
The above post was correctly marked as flamebait, but there's a grain of truth in it. ICC, for example, still does a much better job at vectorisation than gcc or clang (clang with polly enabled does about as well, significantly better in some cases). The autoparallelisation stuff in the Sun, uh, Oracle, compiler is also pretty impressive on certain workloads.